From 5a79d132df1e1a57dcb970177aca9f5c5955aeb8 Mon Sep 17 00:00:00 2001 From: Lucio Correia Date: Thu, 14 May 2015 14:52:49 -0300 Subject: [PATCH] Introduce Wok (Webserver Originated from Kimchi) - Create kimchi plugin - Rename src/kimchi to src/wok - Rename kimchi-named files to wok - Duplicate UI files from kimchi to wok - Add i18n files to wok - Add packaging specs to wok - Add back necessary __init__.py and Makefile.am files to wok - Copy autogen, configure, build-aux, m4 files to plugins/kimchi - Copy documentation files to plugins/kimchi - Add .gitignore to plugins/kimchi for further separation from wok. - Update wok docs - Add API and README docs to reflect new changes introduced by wok. - Update kimchi plugin docs - Add kimchi dependency on wok - Replace gettext-devel dependency by gettext - Rename kimchi_log to wok_log - It now uses wok.min.js for server JS API. - Use plugin relative URLs - Use InternalRedirect for all plugin redirects - Dynamically add authed URLs to plugin conf - Do not use tabs dir for kimchi plugin html templates - Do not generate help index - Fix import_module - Make render_cheetah_file() plugin-aware - Make cachebust's href() plugin-aware - Correctly join help pathes for plugins case - Install plugin .mo files to default locale dir - Adapt automated tests to the new plugin structure - Add specific state_dir values to plugins Signed-off-by: Lucio Correia Signed-off-by: Gustavo Y. Ribeiro --- .gitignore | 18 +- COPYING | 6 +- Makefile.am | 91 +- VERSION | 2 +- configure.ac | 38 +- contrib/DEBIAN/control.in | 18 +- contrib/DEBIAN/postrm | 4 +- contrib/Makefile.am | 12 +- contrib/make-deb.sh.in | 2 +- contrib/wok.spec.fedora.in | 159 + contrib/wok.spec.suse.in | 133 + ...t.conf.fedora => wokd-upstart.conf.debian} | 11 +- contrib/wokd-upstart.conf.fedora | 28 + ...hid.service.fedora => wokd.service.fedora} | 6 +- contrib/{kimchid.sysvinit => wokd.sysvinit} | 18 +- docs/API.md | 1129 +----- docs/Makefile.am | 9 +- docs/README.md | 201 +- docs/{kimchid.8.in => wokd.8.in} | 0 plugins/Makefile.am | 2 +- plugins/kimchi/.gitignore | 37 + {src => plugins}/kimchi/API.json | 12 +- plugins/kimchi/INSTALL | 369 ++ plugins/kimchi/Makefile.am | 159 + 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 | 138 + plugins/kimchi/config.rpath | 672 ++++ plugins/kimchi/configure.ac | 119 + plugins/kimchi/contrib/DEBIAN/Makefile.am | 17 + plugins/kimchi/contrib/DEBIAN/control.in | 37 + .../kimchi/contrib/Makefile.am | 32 +- plugins/kimchi/contrib/check_i18n.py | 82 + .../kimchi/contrib}/kimchi.spec.fedora.in | 99 +- .../kimchi/contrib}/kimchi.spec.suse.in | 71 +- plugins/kimchi/contrib/make-deb.sh.in | 15 + {src => plugins}/kimchi/control/Makefile.am | 2 +- {src => plugins}/kimchi/control/__init__.py | 2 +- {src => plugins}/kimchi/control/config.py | 4 +- {src => plugins}/kimchi/control/cpuinfo.py | 2 +- .../kimchi/control/debugreports.py | 6 +- {src => plugins}/kimchi/control/groups.py | 4 +- {src => plugins}/kimchi/control/host.py | 9 +- {src => plugins}/kimchi/control/interfaces.py | 4 +- {src => plugins}/kimchi/control/networks.py | 4 +- {src => plugins}/kimchi/control/peers.py | 4 +- .../kimchi/control/storagepools.py | 13 +- .../kimchi/control/storageservers.py | 8 +- .../kimchi/control/storagevolumes.py | 8 +- {src => plugins}/kimchi/control/tasks.py | 4 +- {src => plugins}/kimchi/control/templates.py | 4 +- {src => plugins}/kimchi/control/users.py | 6 +- .../kimchi/control/vm/Makefile.am | 2 +- .../kimchi/control/vm/__init__.py | 2 +- .../kimchi/control/vm/hostdevs.py | 4 +- {src => plugins}/kimchi/control/vm/ifaces.py | 4 +- .../kimchi/control/vm/snapshots.py | 4 +- .../kimchi/control/vm/storages.py | 4 +- {src => plugins}/kimchi/control/vms.py | 7 +- {src => plugins}/kimchi/disks.py | 11 +- {src => plugins}/kimchi/distroloader.py | 11 +- {src => plugins/kimchi}/distros.d/Makefile.am | 0 {src => plugins/kimchi}/distros.d/debian.json | 0 {src => plugins/kimchi}/distros.d/fedora.json | 0 {src => plugins/kimchi}/distros.d/gentoo.json | 0 .../kimchi}/distros.d/opensuse.json | 0 {src => plugins/kimchi}/distros.d/ubuntu.json | 0 plugins/kimchi/docs/API.md | 1153 ++++++ plugins/kimchi/docs/Makefile.am | 28 + .../kimchi/docs}/README-federation.md | 18 +- plugins/kimchi/docs/README.md | 246 ++ .../kimchi/docs}/kimchi-guest.png | Bin .../kimchi/docs}/kimchi-login.png | Bin .../kimchi/docs}/kimchi-templates.png | Bin {src => plugins}/kimchi/i18n.py | 20 +- {src => plugins}/kimchi/imageinfo.py | 8 +- {src => plugins}/kimchi/iscsi.py | 2 +- {src => plugins}/kimchi/isoinfo.py | 8 +- plugins/kimchi/kimchi.conf | 37 + {src => plugins}/kimchi/kvmusertests.py | 4 +- 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 + {src => plugins}/kimchi/mockmodel.py | 73 +- plugins/kimchi/model/Makefile.am | 25 + {src => plugins}/kimchi/model/__init__.py | 0 {src => plugins}/kimchi/model/config.py | 35 +- {src => plugins}/kimchi/model/cpuinfo.py | 12 +- {src => plugins}/kimchi/model/debugreports.py | 36 +- {src => plugins}/kimchi/model/diskutils.py | 16 +- {src => plugins}/kimchi/model/featuretests.py | 12 +- {src => plugins}/kimchi/model/groups.py | 2 +- {src => plugins}/kimchi/model/host.py | 42 +- {src => plugins}/kimchi/model/hostdev.py | 17 +- {src => plugins}/kimchi/model/interfaces.py | 7 +- .../kimchi/model/libvirtconnection.py | 25 +- .../kimchi/model/libvirtstoragepool.py | 14 +- {src => plugins}/kimchi/model/model.py | 11 +- {src => plugins}/kimchi/model/networks.py | 46 +- {src => plugins}/kimchi/model/peers.py | 20 +- {src => plugins}/kimchi/model/storagepools.py | 73 +- .../kimchi/model/storageservers.py | 5 +- .../kimchi/model/storagetargets.py | 11 +- .../kimchi/model/storagevolumes.py | 35 +- {src => plugins}/kimchi/model/tasks.py | 2 +- {src => plugins}/kimchi/model/templates.py | 24 +- {src => plugins}/kimchi/model/users.py | 4 +- {src => plugins}/kimchi/model/utils.py | 3 +- {src => plugins}/kimchi/model/vmhostdevs.py | 26 +- {src => plugins}/kimchi/model/vmifaces.py | 14 +- {src => plugins}/kimchi/model/vms.py | 114 +- {src => plugins}/kimchi/model/vmsnapshots.py | 20 +- {src => plugins}/kimchi/model/vmstorages.py | 37 +- {src => plugins}/kimchi/netinfo.py | 0 {src => plugins}/kimchi/network.py | 0 {src => plugins}/kimchi/osinfo.py | 14 +- 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 | 2506 ++++++++++++ plugins/kimchi/po/en_US.po | 2188 ++++++++++ plugins/kimchi/po/es_ES.po | 2498 ++++++++++++ plugins/kimchi/po/fr_FR.po | 2507 ++++++++++++ plugins/kimchi/po/gen-pot.in | 9 + plugins/kimchi/po/it_IT.po | 2460 ++++++++++++ plugins/kimchi/po/ja_JP.po | 2441 ++++++++++++ {po => plugins/kimchi/po}/kimchi.pot | 0 plugins/kimchi/po/ko_KR.po | 2329 +++++++++++ plugins/kimchi/po/pt_BR.po | 2459 ++++++++++++ plugins/kimchi/po/ru_RU.po | 2379 +++++++++++ plugins/kimchi/po/zh_CN.po | 2219 +++++++++++ plugins/kimchi/po/zh_TW.po | 2220 +++++++++++ {src => plugins}/kimchi/repositories.py | 16 +- plugins/kimchi/root.py | 69 + {src => plugins}/kimchi/scan.py | 6 +- {src => plugins}/kimchi/screenshot.py | 14 +- {src => plugins}/kimchi/swupdate.py | 17 +- {src => plugins/kimchi}/template.conf | 0 {tests => plugins/kimchi/tests}/Makefile.am | 2 +- {tests => plugins/kimchi/tests}/iso_gen.py | 3 +- .../kimchi/tests}/run_tests.sh.in | 2 +- .../kimchi/tests}/test_authorization.py | 84 +- plugins/kimchi/tests/test_config.py.in | 289 ++ .../kimchi/tests}/test_exception.py | 33 +- {tests => plugins/kimchi/tests}/test_host.py | 66 +- .../kimchi/tests}/test_mock_network.py | 8 +- .../kimchi/tests}/test_mock_storagepool.py | 20 +- .../kimchi/tests}/test_mock_storagevolume.py | 16 +- .../kimchi/tests}/test_mockmodel.py | 29 +- {tests => plugins/kimchi/tests}/test_model.py | 100 +- .../kimchi/tests}/test_model_network.py | 25 +- .../kimchi/tests}/test_model_storagepool.py | 29 +- .../kimchi/tests}/test_model_storagevolume.py | 35 +- .../kimchi/tests}/test_networkxml.py | 9 +- .../kimchi/tests}/test_objectstore.py | 5 +- .../kimchi/tests}/test_osinfo.py | 5 +- .../kimchi/tests}/test_plugin.py | 10 +- {tests => plugins/kimchi/tests}/test_rest.py | 635 +-- .../kimchi/tests}/test_rollbackcontext.py | 2 +- .../kimchi/tests}/test_server.py | 42 +- .../kimchi/tests}/test_storagepoolxml.py | 2 +- .../kimchi/tests}/test_template.py | 111 +- {tests => plugins/kimchi/tests}/test_utils.py | 4 +- .../kimchi/tests}/test_vmtemplate.py | 6 +- .../kimchi/tests}/test_yumparser.py | 13 +- {tests => plugins/kimchi/tests}/utils.py | 36 +- {config => plugins/kimchi/ui}/Makefile.am | 4 +- .../kimchi/ui/config}/Makefile.am | 4 +- .../kimchi/ui/config/tab-ext.xml | 14 +- plugins/kimchi/ui/css/Makefile.am | 26 + .../ui}/css/theme-default/guest-edit.css | 6 +- .../css/theme-default/guest-storage-add.css | 0 .../kimchi/ui}/css/theme-default/host.css | 4 +- plugins/kimchi/ui/css/theme-default/icon.css | 106 + .../kimchi/ui}/css/theme-default/list.css | 2 +- .../kimchi/ui}/css/theme-default/network.css | 4 +- .../ui}/css/theme-default/report-add.css | 0 .../ui}/css/theme-default/report-rename.css | 2 +- .../ui}/css/theme-default/repository-add.css | 0 .../ui}/css/theme-default/repository-edit.css | 0 .../kimchi/ui}/css/theme-default/storage.css | 6 +- .../theme-default/storagepool-add-volume.css | 0 .../ui}/css/theme-default/template-edit.css | 0 .../kimchi/ui}/css/theme-default/template.css | 0 .../ui}/css/theme-default/template_add.css | 6 +- .../ui}/css/theme-default/template_list.css | 0 plugins/kimchi/ui/images/Makefile.am | 22 + .../kimchi/ui}/images/icon-centos.png | Bin .../kimchi/ui}/images/icon-debian.png | Bin .../kimchi/ui}/images/icon-fedora.png | Bin .../kimchi/ui}/images/icon-gentoo.png | Bin .../kimchi/ui}/images/icon-opensuse.png | Bin .../kimchi/ui}/images/icon-ubuntu.png | Bin {ui => plugins/kimchi/ui}/images/icon-vm.png | Bin .../ui/images/theme-default}/Makefile.am | 4 +- .../ui}/images/theme-default/ac22_pause.png | Bin .../images/theme-default/ac22_pause_grey.png | Bin .../ui}/images/theme-default/ac24_resume.png | Bin .../images/theme-default/ac24_resume_grey.png | Bin .../images/theme-default/arrow-down-black.png | Bin 0 -> 2942 bytes .../theme-default/arrow-down-disable.png | Bin .../ui/images/theme-default/arrow-down.png | Bin 0 -> 537 bytes .../ui}/images/theme-default/arrow-up.png | Bin .../ui}/images/theme-default/arrow_out.png | Bin .../kimchi/ui}/images/theme-default/group.png | Bin .../images/theme-default/host-icon-sprite.png | Bin .../ui}/images/theme-default/icon-back.png | Bin .../ui}/images/theme-default/icon-camera.png | Bin .../ui}/images/theme-default/icon-design.png | Bin .../ui}/images/theme-default/icon-detail.png | Bin .../ui}/images/theme-default/icon-iso.png | Bin .../ui}/images/theme-default/icon-list.png | Bin .../ui}/images/theme-default/icon-load.png | Bin .../ui}/images/theme-default/icon-local.png | Bin .../images/theme-default/icon-power-down.png | Bin .../images/theme-default/icon-power-up.png | Bin .../ui}/images/theme-default/icon-qcow2.png | Bin .../ui}/images/theme-default/icon-raw.png | Bin .../ui}/images/theme-default/icon-remote.png | Bin .../ui}/images/theme-default/icon-reset.png | Bin .../ui}/images/theme-default/icon-search.png | Bin .../ui}/images/theme-default/icon-sort.png | Bin .../ui}/images/theme-default/icon-tree.png | Bin .../ui}/images/theme-default/icon-user.png | Bin .../theme-default/icon-volume-default.png | Bin .../theme-default/kimchi-loading15x15.gif | Bin .../ui}/images/theme-default/loading.gif | Bin .../kimchi/ui}/images/theme-default/user.png | Bin plugins/kimchi/ui/js/Makefile.am | 27 + .../kimchi/ui}/js/src/kimchi.api.js | 488 +-- .../ui}/js/src/kimchi.guest_add_main.js | 14 +- .../ui}/js/src/kimchi.guest_edit_main.js | 54 +- .../kimchi/ui}/js/src/kimchi.guest_main.js | 46 +- .../ui}/js/src/kimchi.guest_media_main.js | 8 +- .../js/src/kimchi.guest_storage_add.main.js | 14 +- .../kimchi/ui}/js/src/kimchi.host.js | 84 +- plugins/kimchi/ui/js/src/kimchi.main.js | 26 + .../kimchi/ui}/js/src/kimchi.network.js | 36 +- .../ui}/js/src/kimchi.report_add_main.js | 10 +- .../ui}/js/src/kimchi.report_rename_main.js | 10 +- .../ui}/js/src/kimchi.repository_add_main.js | 6 +- .../ui}/js/src/kimchi.repository_edit_main.js | 6 +- .../kimchi/ui}/js/src/kimchi.storage_main.js | 68 +- .../ui}/js/src/kimchi.storagepool_add_main.js | 26 +- .../src/kimchi.storagepool_add_volume_main.js | 18 +- .../ui}/js/src/kimchi.template_add_main.js | 34 +- .../ui}/js/src/kimchi.template_edit_main.js | 14 +- .../kimchi/ui}/js/src/kimchi.template_main.js | 22 +- plugins/kimchi/ui/pages/Makefile.am | 22 + .../kimchi/ui}/pages/guest-add.html.tmpl | 4 +- .../kimchi/ui}/pages/guest-edit.html.tmpl | 0 .../ui}/pages/guest-storage-add.html.tmpl | 2 +- .../kimchi/ui}/pages/guest.html.tmpl | 4 +- .../kimchi/ui/pages}/guests.html.tmpl | 11 +- .../kimchi/ui}/pages/help/Makefile.am | 7 +- .../kimchi/ui}/pages/help/de_DE/Makefile.am | 2 +- .../kimchi/ui}/pages/help/de_DE/guests.dita | 0 .../kimchi/ui}/pages/help/de_DE/host.dita | 0 .../kimchi/ui}/pages/help/de_DE/network.dita | 0 .../kimchi/ui}/pages/help/de_DE/storage.dita | 0 .../ui}/pages/help/de_DE/templates.dita | 0 .../kimchi/ui}/pages/help/dita-help.xsl | 2 +- .../kimchi/ui}/pages/help/en_US/Makefile.am | 2 +- .../kimchi/ui}/pages/help/en_US/guests.dita | 0 .../kimchi/ui}/pages/help/en_US/host.dita | 0 .../kimchi/ui}/pages/help/en_US/network.dita | 0 .../kimchi/ui}/pages/help/en_US/storage.dita | 0 .../ui}/pages/help/en_US/templates.dita | 0 .../kimchi/ui}/pages/help/es_ES/Makefile.am | 2 +- .../kimchi/ui}/pages/help/es_ES/guests.dita | 0 .../kimchi/ui}/pages/help/es_ES/host.dita | 0 .../kimchi/ui}/pages/help/es_ES/network.dita | 0 .../kimchi/ui}/pages/help/es_ES/storage.dita | 0 .../ui}/pages/help/es_ES/templates.dita | 0 .../kimchi/ui}/pages/help/fr_FR/Makefile.am | 2 +- .../kimchi/ui}/pages/help/fr_FR/guests.dita | 0 .../kimchi/ui}/pages/help/fr_FR/host.dita | 0 .../kimchi/ui}/pages/help/fr_FR/network.dita | 0 .../kimchi/ui}/pages/help/fr_FR/storage.dita | 0 .../ui}/pages/help/fr_FR/templates.dita | 0 .../kimchi/ui}/pages/help/it_IT/Makefile.am | 2 +- .../kimchi/ui}/pages/help/it_IT/guests.dita | 0 .../kimchi/ui}/pages/help/it_IT/host.dita | 0 .../kimchi/ui}/pages/help/it_IT/network.dita | 0 .../kimchi/ui}/pages/help/it_IT/storage.dita | 0 .../ui}/pages/help/it_IT/templates.dita | 0 .../kimchi/ui}/pages/help/ja_JP/Makefile.am | 2 +- .../kimchi/ui}/pages/help/ja_JP/guests.dita | 0 .../kimchi/ui}/pages/help/ja_JP/host.dita | 0 .../kimchi/ui}/pages/help/ja_JP/network.dita | 0 .../kimchi/ui}/pages/help/ja_JP/storage.dita | 0 .../ui}/pages/help/ja_JP/templates.dita | 0 .../kimchi/ui}/pages/help/kimchi.css | 0 .../kimchi/ui}/pages/help/ko_KR/Makefile.am | 2 +- .../kimchi/ui}/pages/help/ko_KR/guests.dita | 0 .../kimchi/ui}/pages/help/ko_KR/host.dita | 0 .../kimchi/ui}/pages/help/ko_KR/network.dita | 0 .../kimchi/ui}/pages/help/ko_KR/storage.dita | 0 .../ui}/pages/help/ko_KR/templates.dita | 0 .../kimchi/ui}/pages/help/pt_BR/Makefile.am | 2 +- .../kimchi/ui}/pages/help/pt_BR/guests.dita | 0 .../kimchi/ui}/pages/help/pt_BR/host.dita | 0 .../kimchi/ui}/pages/help/pt_BR/network.dita | 0 .../kimchi/ui}/pages/help/pt_BR/storage.dita | 0 .../ui}/pages/help/pt_BR/templates.dita | 0 .../kimchi/ui}/pages/help/ru_RU/Makefile.am | 2 +- .../kimchi/ui}/pages/help/ru_RU/guests.dita | 0 .../kimchi/ui}/pages/help/ru_RU/host.dita | 0 .../kimchi/ui}/pages/help/ru_RU/network.dita | 0 .../kimchi/ui}/pages/help/ru_RU/storage.dita | 0 .../ui}/pages/help/ru_RU/templates.dita | 0 .../kimchi/ui}/pages/help/zh_CN/Makefile.am | 2 +- .../kimchi/ui}/pages/help/zh_CN/guests.dita | 0 .../kimchi/ui}/pages/help/zh_CN/host.dita | 0 .../kimchi/ui}/pages/help/zh_CN/network.dita | 0 .../kimchi/ui}/pages/help/zh_CN/storage.dita | 0 .../ui}/pages/help/zh_CN/templates.dita | 0 .../kimchi/ui}/pages/help/zh_TW/Makefile.am | 2 +- .../kimchi/ui}/pages/help/zh_TW/guests.dita | 0 .../kimchi/ui}/pages/help/zh_TW/host.dita | 0 .../kimchi/ui}/pages/help/zh_TW/network.dita | 0 .../kimchi/ui}/pages/help/zh_TW/storage.dita | 0 .../ui}/pages/help/zh_TW/templates.dita | 0 .../kimchi/ui/pages}/host.html.tmpl | 11 +- plugins/kimchi/ui/pages/i18n.json.tmpl | 187 + .../kimchi/ui/pages}/network.html.tmpl | 6 +- .../kimchi/ui}/pages/report-add.html.tmpl | 2 +- .../kimchi/ui}/pages/report-rename.html.tmpl | 2 +- .../kimchi/ui}/pages/repository-add.html.tmpl | 2 +- .../ui}/pages/repository-edit.html.tmpl | 2 +- .../kimchi/ui/pages}/storage.html.tmpl | 6 +- .../pages/storagepool-add-volume.html.tmpl | 2 +- .../ui}/pages/storagepool-add.html.tmpl | 2 +- .../kimchi/ui}/pages/template-add.html.tmpl | 4 +- .../kimchi/ui}/pages/template-edit.html.tmpl | 2 +- .../kimchi/ui/pages}/templates.html.tmpl | 6 +- plugins/kimchi/ui/robots.txt | 2 + .../kimchi/ui}/spice-html5/Makefile.am | 2 +- .../kimchi/ui}/spice-html5/atKeynames.js | 0 .../kimchi/ui}/spice-html5/bitmap.js | 0 .../kimchi/ui}/spice-html5/css/Makefile.am | 2 +- .../kimchi/ui}/spice-html5/css/spice.css | 0 .../kimchi/ui}/spice-html5/cursor.js | 0 .../kimchi/ui}/spice-html5/display.js | 0 .../kimchi/ui}/spice-html5/enums.js | 0 .../kimchi/ui}/spice-html5/inputs.js | 0 {ui => plugins/kimchi/ui}/spice-html5/lz.js | 0 {ui => plugins/kimchi/ui}/spice-html5/main.js | 0 .../kimchi/ui}/spice-html5/pages/Makefile.am | 2 +- .../ui}/spice-html5/pages/spice_auto.html | 2 +- .../kimchi/ui}/spice-html5/playback.js | 0 {ui => plugins/kimchi/ui}/spice-html5/png.js | 0 {ui => plugins/kimchi/ui}/spice-html5/quic.js | 0 .../kimchi/ui}/spice-html5/resize.js | 0 .../kimchi/ui}/spice-html5/simulatecursor.js | 0 .../ui}/spice-html5/spicearraybuffer.js | 0 .../kimchi/ui}/spice-html5/spiceconn.js | 0 .../kimchi/ui}/spice-html5/spicedataview.js | 0 .../kimchi/ui}/spice-html5/spicemsg.js | 0 .../kimchi/ui}/spice-html5/spicetype.js | 0 .../ui}/spice-html5/thirdparty/Makefile.am | 2 +- .../kimchi/ui}/spice-html5/thirdparty/jsbn.js | 0 .../ui}/spice-html5/thirdparty/prng4.js | 0 .../kimchi/ui}/spice-html5/thirdparty/rng.js | 0 .../kimchi/ui}/spice-html5/thirdparty/rsa.js | 0 .../kimchi/ui}/spice-html5/thirdparty/sha1.js | 0 .../kimchi/ui}/spice-html5/ticket.js | 0 .../kimchi/ui}/spice-html5/utils.js | 0 {ui => plugins/kimchi/ui}/spice-html5/webm.js | 0 {ui => plugins/kimchi/ui}/spice-html5/wire.js | 0 plugins/kimchi/utils.py | 39 + {src => plugins}/kimchi/vmtemplate.py | 25 +- plugins/kimchi/xmlutils/Makefile.am | 25 + {src => plugins}/kimchi/xmlutils/__init__.py | 0 {src => plugins}/kimchi/xmlutils/cpu.py | 0 {src => plugins}/kimchi/xmlutils/disk.py | 6 +- {src => plugins}/kimchi/xmlutils/graphics.py | 1 - {src => plugins}/kimchi/xmlutils/interface.py | 3 +- {src => plugins}/kimchi/xmlutils/network.py | 1 - .../kimchi/xmlutils/qemucmdline.py | 0 {src => plugins}/kimchi/yumparser.py | 0 plugins/sample/API.json | 2 +- plugins/sample/__init__.py | 14 +- plugins/sample/model.py | 4 +- plugins/sample/sample.conf.in | 12 +- plugins/sample/ui/js/util.js | 6 +- .../ui/pages/help/en_US/sample-tab1.html | 2 +- .../ui/pages/help/en_US/sample-tab2.html | 2 +- plugins/sample/ui/pages/i18n.json.tmpl | 2 +- po/Makevars | 2 +- po/POTFILES.in | 3 +- po/de_DE.po | 3101 ++++++--------- po/en_US.po | 2038 +--------- po/es_ES.po | 3108 ++++++--------- po/fr_FR.po | 3470 +++++++--------- po/gen-pot.in | 2 +- po/it_IT.po | 3038 ++++++-------- po/ja_JP.po | 3052 ++++++-------- po/ko_KR.po | 2779 +++++-------- po/pt_BR.po | 3531 ++++++++--------- po/ru_RU.po | 2859 +++++-------- po/wok.pot | 553 +++ po/zh_CN.po | 2909 ++++++-------- po/zh_TW.po | 2634 +++++------- src/Makefile.am | 24 +- src/firewalld.xml | 4 +- src/nginx/Makefile.am | 6 +- src/nginx/{kimchi.conf.in => wok.conf.in} | 8 +- src/{kimchi.conf.in => wok.conf.in} | 14 +- src/wok/API.json | 6 + src/{kimchi => wok}/Makefile.am | 18 +- src/{kimchi => wok}/__init__.py | 0 src/{kimchi => wok}/asynctask.py | 2 +- src/{kimchi => wok}/auth.py | 18 +- src/{kimchi => wok}/basemodel.py | 0 src/{kimchi => wok}/cachebust.py | 11 +- src/{kimchi => wok}/config.py.in | 163 +- src/wok/control/Makefile.am | 25 + src/wok/control/__init__.py | 26 + src/{kimchi => wok}/control/base.py | 36 +- src/{kimchi => wok}/control/plugins.py | 4 +- src/{kimchi => wok}/control/utils.py | 8 +- src/{kimchi => wok}/exception.py | 26 +- src/wok/i18n.py | 47 + src/{kimchi => wok}/model/Makefile.am | 2 +- src/wok/model/__init__.py | 18 + src/wok/model/model.py | 49 + src/{kimchi => wok}/model/plugins.py | 2 +- src/{kimchi => wok}/objectstore.py | 9 +- src/{kimchi => wok}/proxy.py | 22 +- src/{kimchi => wok}/rollbackcontext.py | 0 src/{kimchi => wok}/root.py | 29 +- src/{kimchi => wok}/server.py | 80 +- src/{kimchi => wok}/sslcert.py | 2 - src/{kimchi => wok}/template.py | 13 +- src/{kimchi => wok}/utils.py | 60 +- src/{kimchi => wok}/vnc.py | 9 +- src/{kimchi => wok}/xmlutils/Makefile.am | 2 +- src/wok/xmlutils/__init__.py | 18 + src/{kimchi => wok}/xmlutils/utils.py | 0 src/{kimchid.in => wokd.in} | 12 +- tests/test_config.py.in | 202 - ui/Makefile.am | 4 +- ui/base64/Makefile.am | 2 +- ui/css/Makefile.am | 2 +- ui/css/theme-default/button.css | 85 - ui/css/theme-default/grid.css | 2 +- ui/css/theme-default/topbar.css | 4 + ui/images/Makefile.am | 4 +- ui/images/theme-default/Makefile.am | 2 +- .../{kimchi-loading.gif => wok-loading.gif} | Bin ui/js/Makefile.am | 8 +- ui/js/src/wok.api.js | 91 + ui/js/src/{kimchi.cookie.js => wok.cookie.js} | 2 +- ui/js/src/{kimchi.form.js => wok.form.js} | 0 ui/js/src/{kimchi.grid.js => wok.grid.js} | 12 +- ui/js/src/{kimchi.lang.js => wok.lang.js} | 6 +- ...kimchi.line-chart.js => wok.line-chart.js} | 8 +- ui/js/src/{kimchi.login.js => wok.login.js} | 14 +- ui/js/src/{kimchi.main.js => wok.main.js} | 91 +- .../src/{kimchi.message.js => wok.message.js} | 20 +- ui/js/src/{kimchi.object.js => wok.object.js} | 0 .../src/{kimchi.popable.js => wok.popable.js} | 4 +- ui/js/src/{kimchi.select.js => wok.select.js} | 2 +- ui/js/src/{kimchi.string.js => wok.string.js} | 0 ...kimchi.substitute.js => wok.substitute.js} | 2 +- ui/js/src/{kimchi.topic.js => wok.topic.js} | 8 +- ui/js/src/{kimchi.user.js => wok.user.js} | 6 +- ui/js/src/{kimchi.utils.js => wok.utils.js} | 18 +- ui/js/src/{kimchi.window.js => wok.window.js} | 4 +- ui/js/widgets/button-dropDown.js | 2 +- ui/js/widgets/button-flat.js | 2 +- ui/js/widgets/checkbox-flat.js | 4 +- ui/js/widgets/circleGauge.js | 4 +- ui/js/widgets/combobox.js | 2 +- ui/js/widgets/dialog-flat.js | 4 +- ui/js/widgets/filter-select.js | 2 +- ui/js/widgets/gauge-flat.js | 2 +- ui/js/widgets/grid.js | 2 +- ui/js/widgets/line.js | 2 +- ui/js/widgets/list-flat.js | 4 +- ui/js/widgets/menu-flat.js | 4 +- ui/js/widgets/message-flat.js | 4 +- ui/js/widgets/messagebar-flat.js | 4 +- ui/js/widgets/radio-flat.js | 4 +- ui/js/widgets/samples/grid.html | 4 +- ui/js/widgets/samples/line.html | 4 +- ui/js/widgets/samples/tabs.html | 4 +- ui/js/widgets/select-menu.js | 2 +- ui/js/widgets/selectmenu-flat.js | 4 +- ui/js/widgets/textbox-flat.js | 4 +- ui/libs/Makefile.am | 2 +- ui/libs/themes/base/Makefile.am | 2 +- ui/libs/themes/base/images/Makefile.am | 2 +- ui/pages/Makefile.am | 4 +- ui/pages/error.html.tmpl | 8 +- ui/pages/help/gen-index.py | 63 - ui/pages/i18n.json.tmpl | 2 +- ui/pages/login.html.tmpl | 8 +- ui/pages/websockify/Makefile.am | 2 +- ui/pages/websockify/console.html | 12 +- .../{kimchi-ui.html.tmpl => wok-ui.html.tmpl} | 12 +- 515 files changed, 49672 insertions(+), 24401 deletions(-) create mode 100644 contrib/wok.spec.fedora.in create mode 100644 contrib/wok.spec.suse.in rename contrib/{kimchid-upstart.conf.fedora => wokd-upstart.conf.debian} (79%) create mode 100644 contrib/wokd-upstart.conf.fedora rename contrib/{kimchid.service.fedora => wokd.service.fedora} (58%) rename contrib/{kimchid.sysvinit => wokd.sysvinit} (89%) rename docs/{kimchid.8.in => wokd.8.in} (100%) create mode 100644 plugins/kimchi/.gitignore rename {src => plugins}/kimchi/API.json (98%) create mode 100644 plugins/kimchi/INSTALL create mode 100644 plugins/kimchi/Makefile.am create mode 120000 plugins/kimchi/README.md create mode 100644 plugins/kimchi/VERSION create mode 100644 plugins/kimchi/__init__.py create mode 100755 plugins/kimchi/autogen.sh create mode 100644 plugins/kimchi/build-aux/config.rpath create mode 100755 plugins/kimchi/build-aux/genChangelog create mode 100755 plugins/kimchi/build-aux/pkg-version create mode 100644 plugins/kimchi/config.py.in create mode 100644 plugins/kimchi/config.rpath create mode 100644 plugins/kimchi/configure.ac create mode 100644 plugins/kimchi/contrib/DEBIAN/Makefile.am create mode 100644 plugins/kimchi/contrib/DEBIAN/control.in rename contrib/kimchid-upstart.conf.debian => plugins/kimchi/contrib/Makefile.am (59%) create mode 100755 plugins/kimchi/contrib/check_i18n.py rename {contrib => plugins/kimchi/contrib}/kimchi.spec.fedora.in (55%) rename {contrib => plugins/kimchi/contrib}/kimchi.spec.suse.in (63%) create mode 100644 plugins/kimchi/contrib/make-deb.sh.in rename {src => plugins}/kimchi/control/Makefile.am (94%) rename {src => plugins}/kimchi/control/__init__.py (94%) rename {src => plugins}/kimchi/control/config.py (94%) rename {src => plugins}/kimchi/control/cpuinfo.py (96%) rename {src => plugins}/kimchi/control/debugreports.py (92%) rename {src => plugins}/kimchi/control/groups.py (91%) rename {src => plugins}/kimchi/control/host.py (95%) rename {src => plugins}/kimchi/control/interfaces.py (94%) rename {src => plugins}/kimchi/control/networks.py (95%) rename {src => plugins}/kimchi/control/peers.py (91%) rename {src => plugins}/kimchi/control/storagepools.py (91%) rename {src => plugins}/kimchi/control/storageservers.py (89%) rename {src => plugins}/kimchi/control/storagevolumes.py (92%) rename {src => plugins}/kimchi/control/tasks.py (91%) rename {src => plugins}/kimchi/control/templates.py (95%) rename {src => plugins}/kimchi/control/users.py (88%) rename {src => plugins}/kimchi/control/vm/Makefile.am (94%) rename {src => plugins}/kimchi/control/vm/__init__.py (94%) rename {src => plugins}/kimchi/control/vm/hostdevs.py (93%) rename {src => plugins}/kimchi/control/vm/ifaces.py (93%) rename {src => plugins}/kimchi/control/vm/snapshots.py (94%) rename {src => plugins}/kimchi/control/vm/storages.py (93%) rename {src => plugins}/kimchi/control/vms.py (93%) rename {src => plugins}/kimchi/disks.py (97%) rename {src => plugins}/kimchi/distroloader.py (91%) rename {src => plugins/kimchi}/distros.d/Makefile.am (100%) rename {src => plugins/kimchi}/distros.d/debian.json (100%) rename {src => plugins/kimchi}/distros.d/fedora.json (100%) rename {src => plugins/kimchi}/distros.d/gentoo.json (100%) rename {src => plugins/kimchi}/distros.d/opensuse.json (100%) rename {src => plugins/kimchi}/distros.d/ubuntu.json (100%) create mode 100644 plugins/kimchi/docs/API.md create mode 100644 plugins/kimchi/docs/Makefile.am rename {docs => plugins/kimchi/docs}/README-federation.md (70%) create mode 100644 plugins/kimchi/docs/README.md rename {docs => plugins/kimchi/docs}/kimchi-guest.png (100%) rename {docs => plugins/kimchi/docs}/kimchi-login.png (100%) rename {docs => plugins/kimchi/docs}/kimchi-templates.png (100%) rename {src => plugins}/kimchi/i18n.py (95%) rename {src => plugins}/kimchi/imageinfo.py (90%) rename {src => plugins}/kimchi/iscsi.py (98%) rename {src => plugins}/kimchi/isoinfo.py (99%) create mode 100644 plugins/kimchi/kimchi.conf rename {src => plugins}/kimchi/kvmusertests.py (97%) create mode 100644 plugins/kimchi/m4/ac_python_module.m4 create mode 100644 plugins/kimchi/m4/gettext.m4 create mode 100644 plugins/kimchi/m4/iconv.m4 create mode 100644 plugins/kimchi/m4/intlmacosx.m4 create mode 100644 plugins/kimchi/m4/lib-ld.m4 create mode 100644 plugins/kimchi/m4/lib-link.m4 create mode 100644 plugins/kimchi/m4/lib-prefix.m4 create mode 100644 plugins/kimchi/m4/nls.m4 create mode 100644 plugins/kimchi/m4/po.m4 create mode 100644 plugins/kimchi/m4/progtest.m4 rename {src => plugins}/kimchi/mockmodel.py (93%) create mode 100644 plugins/kimchi/model/Makefile.am rename {src => plugins}/kimchi/model/__init__.py (100%) rename {src => plugins}/kimchi/model/config.py (86%) rename {src => plugins}/kimchi/model/cpuinfo.py (94%) rename {src => plugins}/kimchi/model/debugreports.py (88%) rename {src => plugins}/kimchi/model/diskutils.py (85%) rename {src => plugins}/kimchi/model/featuretests.py (96%) rename {src => plugins}/kimchi/model/groups.py (98%) rename {src => plugins}/kimchi/model/host.py (96%) rename {src => plugins}/kimchi/model/hostdev.py (95%) rename {src => plugins}/kimchi/model/interfaces.py (91%) rename {src => plugins}/kimchi/model/libvirtconnection.py (87%) rename {src => plugins}/kimchi/model/libvirtstoragepool.py (97%) rename {src => plugins}/kimchi/model/model.py (86%) rename {src => plugins}/kimchi/model/networks.py (93%) rename {src => plugins}/kimchi/model/peers.py (78%) rename {src => plugins}/kimchi/model/storagepools.py (89%) rename {src => plugins}/kimchi/model/storageservers.py (95%) rename {src => plugins}/kimchi/model/storagetargets.py (93%) rename {src => plugins}/kimchi/model/storagevolumes.py (95%) rename {src => plugins}/kimchi/model/tasks.py (97%) rename {src => plugins}/kimchi/model/templates.py (96%) rename {src => plugins}/kimchi/model/users.py (97%) rename {src => plugins}/kimchi/model/utils.py (98%) rename {src => plugins}/kimchi/model/vmhostdevs.py (95%) rename {src => plugins}/kimchi/model/vmifaces.py (96%) rename {src => plugins}/kimchi/model/vms.py (93%) rename {src => plugins}/kimchi/model/vmsnapshots.py (94%) rename {src => plugins}/kimchi/model/vmstorages.py (90%) rename {src => plugins}/kimchi/netinfo.py (100%) rename {src => plugins}/kimchi/network.py (100%) rename {src => plugins}/kimchi/osinfo.py (94%) create mode 100644 plugins/kimchi/po/LINGUAS create mode 100644 plugins/kimchi/po/Makefile.in.in create mode 100644 plugins/kimchi/po/Makevars create mode 100644 plugins/kimchi/po/POTFILES.in create mode 100644 plugins/kimchi/po/de_DE.po create mode 100644 plugins/kimchi/po/en_US.po create mode 100644 plugins/kimchi/po/es_ES.po create mode 100644 plugins/kimchi/po/fr_FR.po create mode 100644 plugins/kimchi/po/gen-pot.in create mode 100644 plugins/kimchi/po/it_IT.po create mode 100644 plugins/kimchi/po/ja_JP.po rename {po => plugins/kimchi/po}/kimchi.pot (100%) create mode 100644 plugins/kimchi/po/ko_KR.po create mode 100644 plugins/kimchi/po/pt_BR.po create mode 100644 plugins/kimchi/po/ru_RU.po create mode 100644 plugins/kimchi/po/zh_CN.po create mode 100644 plugins/kimchi/po/zh_TW.po rename {src => plugins}/kimchi/repositories.py (97%) create mode 100644 plugins/kimchi/root.py rename {src => plugins}/kimchi/scan.py (95%) rename {src => plugins}/kimchi/screenshot.py (94%) rename {src => plugins}/kimchi/swupdate.py (95%) rename {src => plugins/kimchi}/template.conf (100%) rename {tests => plugins/kimchi/tests}/Makefile.am (97%) rename {tests => plugins/kimchi/tests}/iso_gen.py (99%) rename {tests => plugins/kimchi/tests}/run_tests.sh.in (94%) rename {tests => plugins/kimchi/tests}/test_authorization.py (62%) create mode 100644 plugins/kimchi/tests/test_config.py.in rename {tests => plugins/kimchi/tests}/test_exception.py (79%) rename {tests => plugins/kimchi/tests}/test_host.py (75%) rename {tests => plugins/kimchi/tests}/test_mock_network.py (92%) rename {tests => plugins/kimchi/tests}/test_mock_storagepool.py (90%) rename {tests => plugins/kimchi/tests}/test_mock_storagevolume.py (87%) rename {tests => plugins/kimchi/tests}/test_mockmodel.py (81%) rename {tests => plugins/kimchi/tests}/test_model.py (94%) rename {tests => plugins/kimchi/tests}/test_model_network.py (86%) rename {tests => plugins/kimchi/tests}/test_model_storagepool.py (81%) rename {tests => plugins/kimchi/tests}/test_model_storagevolume.py (91%) rename {tests => plugins/kimchi/tests}/test_networkxml.py (98%) rename {tests => plugins/kimchi/tests}/test_objectstore.py (97%) rename {tests => plugins/kimchi/tests}/test_osinfo.py (95%) rename {tests => plugins/kimchi/tests}/test_plugin.py (96%) rename {tests => plugins/kimchi/tests}/test_rest.py (63%) rename {tests => plugins/kimchi/tests}/test_rollbackcontext.py (98%) rename {tests => plugins/kimchi/tests}/test_server.py (88%) rename {tests => plugins/kimchi/tests}/test_storagepoolxml.py (98%) rename {tests => plugins/kimchi/tests}/test_template.py (77%) rename {tests => plugins/kimchi/tests}/test_utils.py (97%) rename {tests => plugins/kimchi/tests}/test_vmtemplate.py (96%) rename {tests => plugins/kimchi/tests}/test_yumparser.py (93%) rename {tests => plugins/kimchi/tests}/utils.py (90%) rename {config => plugins/kimchi/ui}/Makefile.am (86%) rename {config/ui => plugins/kimchi/ui/config}/Makefile.am (90%) rename config/ui/tabs.xml => plugins/kimchi/ui/config/tab-ext.xml (73%) create mode 100644 plugins/kimchi/ui/css/Makefile.am rename {ui => plugins/kimchi/ui}/css/theme-default/guest-edit.css (97%) rename {ui => plugins/kimchi/ui}/css/theme-default/guest-storage-add.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/host.css (97%) create mode 100644 plugins/kimchi/ui/css/theme-default/icon.css rename {ui => plugins/kimchi/ui}/css/theme-default/list.css (98%) rename {ui => plugins/kimchi/ui}/css/theme-default/network.css (98%) rename {ui => plugins/kimchi/ui}/css/theme-default/report-add.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/report-rename.css (99%) rename {ui => plugins/kimchi/ui}/css/theme-default/repository-add.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/repository-edit.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/storage.css (98%) rename {ui => plugins/kimchi/ui}/css/theme-default/storagepool-add-volume.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/template-edit.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/template.css (100%) rename {ui => plugins/kimchi/ui}/css/theme-default/template_add.css (96%) rename {ui => plugins/kimchi/ui}/css/theme-default/template_list.css (100%) create mode 100644 plugins/kimchi/ui/images/Makefile.am rename {ui => plugins/kimchi/ui}/images/icon-centos.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-debian.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-fedora.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-gentoo.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-opensuse.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-ubuntu.png (100%) rename {ui => plugins/kimchi/ui}/images/icon-vm.png (100%) rename {ui/pages/tabs => plugins/kimchi/ui/images/theme-default}/Makefile.am (85%) rename {ui => plugins/kimchi/ui}/images/theme-default/ac22_pause.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/ac22_pause_grey.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/ac24_resume.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/ac24_resume_grey.png (100%) create mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down-black.png rename {ui => plugins/kimchi/ui}/images/theme-default/arrow-down-disable.png (100%) create mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down.png rename {ui => plugins/kimchi/ui}/images/theme-default/arrow-up.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/arrow_out.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/group.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/host-icon-sprite.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-back.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-camera.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-design.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-detail.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-iso.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-list.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-load.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-local.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-power-down.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-power-up.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-qcow2.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-raw.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-remote.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-reset.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-search.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-sort.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-tree.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-user.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/icon-volume-default.png (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/kimchi-loading15x15.gif (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/loading.gif (100%) rename {ui => plugins/kimchi/ui}/images/theme-default/user.png (100%) create mode 100644 plugins/kimchi/ui/js/Makefile.am rename {ui => plugins/kimchi/ui}/js/src/kimchi.api.js (72%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.guest_add_main.js (86%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.guest_edit_main.js (94%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.guest_main.js (93%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.guest_media_main.js (85%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.guest_storage_add.main.js (94%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.host.js (91%) create mode 100644 plugins/kimchi/ui/js/src/kimchi.main.js rename {ui => plugins/kimchi/ui}/js/src/kimchi.network.js (92%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.report_add_main.js (89%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.report_rename_main.js (89%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.repository_add_main.js (95%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.repository_edit_main.js (94%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.storage_main.js (86%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.storagepool_add_main.js (94%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.storagepool_add_volume_main.js (91%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.template_add_main.js (93%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.template_edit_main.js (96%) rename {ui => plugins/kimchi/ui}/js/src/kimchi.template_main.js (83%) create mode 100644 plugins/kimchi/ui/pages/Makefile.am rename {ui => plugins/kimchi/ui}/pages/guest-add.html.tmpl (98%) rename {ui => plugins/kimchi/ui}/pages/guest-edit.html.tmpl (100%) rename {ui => plugins/kimchi/ui}/pages/guest-storage-add.html.tmpl (99%) rename {ui => plugins/kimchi/ui}/pages/guest.html.tmpl (97%) rename {ui/pages/tabs => plugins/kimchi/ui/pages}/guests.html.tmpl (89%) rename {ui => plugins/kimchi/ui}/pages/help/Makefile.am (85%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/de_DE/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/dita-help.xsl (92%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/en_US/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/es_ES/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/fr_FR/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/it_IT/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ja_JP/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/kimchi.css (100%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ko_KR/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/pt_BR/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/ru_RU/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_CN/templates.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/Makefile.am (92%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/guests.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/host.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/network.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/storage.dita (100%) rename {ui => plugins/kimchi/ui}/pages/help/zh_TW/templates.dita (100%) rename {ui/pages/tabs => plugins/kimchi/ui/pages}/host.html.tmpl (97%) create mode 100644 plugins/kimchi/ui/pages/i18n.json.tmpl rename {ui/pages/tabs => plugins/kimchi/ui/pages}/network.html.tmpl (97%) rename {ui => plugins/kimchi/ui}/pages/report-add.html.tmpl (98%) rename {ui => plugins/kimchi/ui}/pages/report-rename.html.tmpl (98%) rename {ui => plugins/kimchi/ui}/pages/repository-add.html.tmpl (99%) rename {ui => plugins/kimchi/ui}/pages/repository-edit.html.tmpl (99%) rename {ui/pages/tabs => plugins/kimchi/ui/pages}/storage.html.tmpl (96%) rename {ui => plugins/kimchi/ui}/pages/storagepool-add-volume.html.tmpl (98%) rename {ui => plugins/kimchi/ui}/pages/storagepool-add.html.tmpl (99%) rename {ui => plugins/kimchi/ui}/pages/template-add.html.tmpl (98%) rename {ui => plugins/kimchi/ui}/pages/template-edit.html.tmpl (99%) rename {ui/pages/tabs => plugins/kimchi/ui/pages}/templates.html.tmpl (94%) create mode 100644 plugins/kimchi/ui/robots.txt rename {ui => plugins/kimchi/ui}/spice-html5/Makefile.am (91%) rename {ui => plugins/kimchi/ui}/spice-html5/atKeynames.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/bitmap.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/css/Makefile.am (91%) rename {ui => plugins/kimchi/ui}/spice-html5/css/spice.css (100%) rename {ui => plugins/kimchi/ui}/spice-html5/cursor.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/display.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/enums.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/inputs.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/lz.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/main.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/pages/Makefile.am (90%) rename {ui => plugins/kimchi/ui}/spice-html5/pages/spice_auto.html (98%) rename {ui => plugins/kimchi/ui}/spice-html5/playback.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/png.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/quic.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/resize.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/simulatecursor.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/spicearraybuffer.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/spiceconn.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/spicedataview.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/spicemsg.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/spicetype.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/Makefile.am (89%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/jsbn.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/prng4.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/rng.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/rsa.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/thirdparty/sha1.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/ticket.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/utils.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/webm.js (100%) rename {ui => plugins/kimchi/ui}/spice-html5/wire.js (100%) create mode 100644 plugins/kimchi/utils.py rename {src => plugins}/kimchi/vmtemplate.py (96%) create mode 100644 plugins/kimchi/xmlutils/Makefile.am rename {src => plugins}/kimchi/xmlutils/__init__.py (100%) rename {src => plugins}/kimchi/xmlutils/cpu.py (100%) rename {src => plugins}/kimchi/xmlutils/disk.py (98%) rename {src => plugins}/kimchi/xmlutils/graphics.py (99%) rename {src => plugins}/kimchi/xmlutils/interface.py (98%) rename {src => plugins}/kimchi/xmlutils/network.py (99%) rename {src => plugins}/kimchi/xmlutils/qemucmdline.py (100%) rename {src => plugins}/kimchi/yumparser.py (100%) create mode 100755 po/wok.pot rename src/nginx/{kimchi.conf.in => wok.conf.in} (92%) rename src/{kimchi.conf.in => wok.conf.in} (76%) create mode 100644 src/wok/API.json rename src/{kimchi => wok}/Makefile.am (77%) rename src/{kimchi => wok}/__init__.py (100%) rename src/{kimchi => wok}/asynctask.py (98%) rename src/{kimchi => wok}/auth.py (97%) rename src/{kimchi => wok}/basemodel.py (100%) rename src/{kimchi => wok}/cachebust.py (79%) rename src/{kimchi => wok}/config.py.in (56%) create mode 100644 src/wok/control/Makefile.am create mode 100644 src/wok/control/__init__.py rename src/{kimchi => wok}/control/base.py (92%) rename src/{kimchi => wok}/control/plugins.py (90%) rename src/{kimchi => wok}/control/utils.py (96%) rename src/{kimchi => wok}/exception.py (78%) create mode 100644 src/wok/i18n.py rename src/{kimchi => wok}/model/Makefile.am (95%) create mode 100644 src/wok/model/__init__.py create mode 100644 src/wok/model/model.py rename src/{kimchi => wok}/model/plugins.py (95%) rename src/{kimchi => wok}/objectstore.py (96%) rename src/{kimchi => wok}/proxy.py (83%) rename src/{kimchi => wok}/rollbackcontext.py (100%) rename src/{kimchi => wok}/root.py (90%) rename src/{kimchi => wok}/server.py (71%) rename src/{kimchi => wok}/sslcert.py (99%) rename src/{kimchi => wok}/template.py (94%) rename src/{kimchi => wok}/utils.py (92%) rename src/{kimchi => wok}/vnc.py (92%) rename src/{kimchi => wok}/xmlutils/Makefile.am (95%) create mode 100644 src/wok/xmlutils/__init__.py rename src/{kimchi => wok}/xmlutils/utils.py (100%) rename src/{kimchid.in => wokd.in} (94%) delete mode 100644 tests/test_config.py.in rename ui/images/theme-default/{kimchi-loading.gif => wok-loading.gif} (100%) create mode 100644 ui/js/src/wok.api.js rename ui/js/src/{kimchi.cookie.js => wok.cookie.js} (98%) rename ui/js/src/{kimchi.form.js => wok.form.js} (100%) rename ui/js/src/{kimchi.grid.js => wok.grid.js} (98%) rename ui/js/src/{kimchi.lang.js => wok.lang.js} (92%) rename ui/js/src/{kimchi.line-chart.js => wok.line-chart.js} (96%) rename ui/js/src/{kimchi.login.js => wok.login.js} (84%) rename ui/js/src/{kimchi.main.js => wok.main.js} (82%) rename ui/js/src/{kimchi.message.js => wok.message.js} (88%) rename ui/js/src/{kimchi.object.js => wok.object.js} (100%) rename ui/js/src/{kimchi.popable.js => wok.popable.js} (93%) rename ui/js/src/{kimchi.select.js => wok.select.js} (97%) rename ui/js/src/{kimchi.string.js => wok.string.js} (100%) rename ui/js/src/{kimchi.substitute.js => wok.substitute.js} (96%) rename ui/js/src/{kimchi.topic.js => wok.topic.js} (83%) rename ui/js/src/{kimchi.user.js => wok.user.js} (89%) rename ui/js/src/{kimchi.utils.js => wok.utils.js} (92%) rename ui/js/src/{kimchi.window.js => wok.window.js} (96%) delete mode 100755 ui/pages/help/gen-index.py rename ui/pages/{kimchi-ui.html.tmpl => wok-ui.html.tmpl} (93%) diff --git a/.gitignore b/.gitignore index 4757cf79e..142b09389 100644 --- a/.gitignore +++ b/.gitignore @@ -19,19 +19,20 @@ configure config.log config.status contrib/DEBIAN/control -contrib/kimchi.spec.fedora -contrib/kimchi.spec.suse +contrib/wok.spec.fedora +contrib/wok.spec.suse contrib/make-deb.sh -docs/kimchid.8 +docs/wokd.8 *.min.css *.min.js *.gmo stamp-po -kimchi-*.tar.gz -src/kimchid -src/kimchi.conf -src/nginx/kimchi.conf -src/kimchi/config.py +wok-*.tar.gz +wok.spec +src/wokd +src/wok.conf +src/nginx/wok.conf +src/wok/config.py tests/run_tests.sh tests/test_config.py plugins/sample/po/POTFILES @@ -41,4 +42,3 @@ po/gen-pot *.orig *.rej *.pem -ui/pages/help/*/*.html diff --git a/COPYING b/COPYING index 867d1db41..f641eaf94 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ -Kimchi is distributed pursuant to the terms of two different licenses. -The user interface (located in ui/ in this distribution) is governed by -the Apache License version 2.0. +Wok/Kimchi are distributed pursuant to the terms of two different licenses. +The user interface (located in ui/ and plugins/kimchi/ui in this distribution) +is governed by the Apache License version 2.0. Kimchi makes use of different projects and they are placed as below: - the code under ui/spice-html5 is imported from spice-html5 project diff --git a/Makefile.am b/Makefile.am index 0e6e59eea..ab5b7d849 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,9 +16,9 @@ # You should have received a copy of the GNU Lesser General Public # 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 = src ui docs contrib tests po config plugins +SUBDIRS = src ui docs contrib po plugins -man_MANS = docs/kimchid.8 +man_MANS = docs/wokd.8 AUTOMAKE_OPTIONS = foreign @@ -35,12 +35,12 @@ EXTRA_DIST = \ $(NULL) -PEP8_BLACKLIST = *src/kimchi/config.py,*src/kimchi/i18n.py,*tests/test_config.py +PEP8_BLACKLIST = *src/wok/config.py,*src/wok/i18n.py,*plugins/kimchi -SKIP_PYFLAKES_ERR = "\./src/kimchi/websocket\.py" +SKIP_PYFLAKES_ERR = "\./src/wok/websocket\.py" I18N_FILES = plugins/*/i18n.py \ - src/kimchi/i18n.py \ + src/wok/i18n.py \ $(NULL) check-local: @@ -60,7 +60,7 @@ 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 ; \ + ln -sf ../../../po/$$L.gmo $$dir/wok.mo ; \ done < po/LINGUAS # @@ -69,44 +69,41 @@ all-local: install-deb: install cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/ - mkdir -p $(DESTDIR)/var/lib/kimchi/debugreports - mkdir -p $(DESTDIR)/var/lib/kimchi/screenshots - mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens - mkdir -p $(DESTDIR)/var/lib/kimchi/isos - touch $(DESTDIR)/var/lib/kimchi/objectstore + mkdir -p $(DESTDIR)/var/lib/wok/vnc-tokens + touch $(DESTDIR)/var/lib/wok/objectstore $(MKDIR_P) $(DESTDIR)/etc/init $(MKDIR_P) $(DESTDIR)/usr/lib/firewalld/services - cp -R $(top_srcdir)/contrib/kimchid-upstart.conf.debian \ - $(DESTDIR)/etc/init/kimchid.conf + cp -R $(top_srcdir)/contrib/wokd-upstart.conf.debian \ + $(DESTDIR)/etc/init/wokd.conf cp -R $(top_srcdir)/src/firewalld.xml \ - $(DESTDIR)/usr/lib/firewalld/services/kimchid.xml + $(DESTDIR)/usr/lib/firewalld/services/wokd.xml deb: contrib/make-deb.sh $(top_srcdir)/contrib/make-deb.sh -kimchi.spec: contrib/kimchi.spec.fedora contrib/kimchi.spec.suse +wok.spec: contrib/wok.spec.fedora contrib/wok.spec.suse @if test -e /etc/redhat-release; then \ - ln -sf contrib/kimchi.spec.fedora $@ ; \ + ln -sf contrib/wok.spec.fedora $@ ; \ elif test -e /etc/SuSE-release; then \ - ln -sf contrib/kimchi.spec.suse $@ ; \ + ln -sf contrib/wok.spec.suse $@ ; \ else \ echo "Unable to select a spec file for RPM build" ; \ /bin/false ; \ fi -rpm: dist kimchi.spec +rpm: dist wok.spec $(MKDIR_P) rpm/BUILD rpm/RPMS rpm/SOURCES rpm/SPECS rpm/SRPMS - cp $(top_srcdir)/kimchi.spec rpm/SPECS/kimchi.spec + cp $(top_srcdir)/wok.spec rpm/SPECS/wok.spec cp $(DIST_ARCHIVES) rpm/SOURCES - rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/kimchi.spec + rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/wok.spec -fedora-rpm: contrib/kimchi.spec.fedora - ln -sf contrib/kimchi.spec.fedora kimchi.spec +fedora-rpm: contrib/wok.spec.fedora + ln -sf contrib/wok.spec.fedora wok.spec $(MAKE) rpm -suse-rpm: contrib/kimchi.spec.suse - ln -sf contrib/kimchi.spec.suse kimchi.spec +suse-rpm: contrib/wok.spec.suse + ln -sf contrib/wok.spec.suse wok.spec $(MAKE) rpm ChangeLog: @@ -117,39 +114,39 @@ ChangeLog: install-data-local: @if test -d "$(systemdsystemunitdir)" ; then \ mkdir -p $(DESTDIR)/$(systemdsystemunitdir); \ - $(INSTALL_DATA) contrib/kimchid.service.fedora $(DESTDIR)/$(systemdsystemunitdir)/kimchid.service; \ + $(INSTALL_DATA) contrib/wokd.service.fedora $(DESTDIR)/$(systemdsystemunitdir)/wokd.service; \ else \ mkdir -p $(DESTDIR)/etc/init.d/; \ - $(INSTALL_DATA) contrib/kimchid.sysvinit $(DESTDIR)/etc/init.d/kimchid; \ - chmod +x $(DESTDIR)/etc/init.d/kimchid; \ + $(INSTALL_DATA) contrib/wokd.sysvinit $(DESTDIR)/etc/init.d/wokd; \ + chmod +x $(DESTDIR)/etc/init.d/wokd; \ fi; \ if test -d /usr/lib/firewalld/services/; then \ mkdir -p $(DESTDIR)/usr/lib/firewalld/services/; \ - $(INSTALL_DATA) src/firewalld.xml $(DESTDIR)/usr/lib/firewalld/services/kimchid.xml; \ + $(INSTALL_DATA) src/firewalld.xml $(DESTDIR)/usr/lib/firewalld/services/wokd.xml; \ fi; \ - mkdir -p $(DESTDIR)/var/lib/kimchi/{debugreports,screenshots,vnc-tokens,isos} - touch $(DESTDIR)/var/lib/kimchi/objectstore - mkdir -p $(DESTDIR)/var/log/kimchi/ - touch $(DESTDIR)/var/log/kimchi/kimchi-access.log - touch $(DESTDIR)/var/log/kimchi/kimchi-error.log - mkdir -p $(DESTDIR)/etc/kimchi/ - $(INSTALL_DATA) src/dhparams.pem $(DESTDIR)/etc/kimchi/dhparams.pem - touch $(DESTDIR)/etc/nginx/conf.d/kimchi.conf + mkdir -p $(DESTDIR)/var/lib/wok/vnc-tokens + touch $(DESTDIR)/var/lib/wok/objectstore + mkdir -p $(DESTDIR)/var/log/wok/ + touch $(DESTDIR)/var/log/wok/wok-access.log + touch $(DESTDIR)/var/log/wok/wok-error.log + mkdir -p $(DESTDIR)/etc/wok/ + $(INSTALL_DATA) src/dhparams.pem $(DESTDIR)/etc/wok/dhparams.pem + touch $(DESTDIR)/etc/nginx/conf.d/wok.conf uninstall-local: - @if test -f $(systemdsystemunitdir)/kimchid.service; then \ - $(RM) $(DESTDIR)/$(systemdsystemunitdir)/kimchid.service; \ - elif test -f /etc/init.d/kimchid; then \ - $(RM) $(DESTDIR)/etc/init.d/kimchid; \ - $(RM) $(DESTDIR)/etc/init/kimchi.conf; \ + @if test -f $(systemdsystemunitdir)/wokd.service; then \ + $(RM) $(DESTDIR)/$(systemdsystemunitdir)/wokd.service; \ + elif test -f /etc/init.d/wokd; then \ + $(RM) $(DESTDIR)/etc/init.d/wokd; \ + $(RM) $(DESTDIR)/etc/init/wok.conf; \ fi; \ if test -d /usr/lib/firewalld/services/; then \ - $(RM) $(DESTDIR)/usr/lib/firewalld/services/kimchid.xml; \ + $(RM) $(DESTDIR)/usr/lib/firewalld/services/wokd.xml; \ fi; \ - $(RM) -rf $(DESTDIR)/var/lib/kimchi - $(RM) -rf $(DESTDIR)/var/log/kimchi - $(RM) -rf $(DESTDIR)/etc/kimchi - $(RM) $(DESTDIR)/etc/nginx/conf.d/kimchi.conf + $(RM) -rf $(DESTDIR)/var/lib/wok + $(RM) -rf $(DESTDIR)/var/log/wok + $(RM) -rf $(DESTDIR)/etc/wok + $(RM) $(DESTDIR)/etc/nginx/conf.d/wok.conf VERSION: @if test -d .git; then \ @@ -162,4 +159,4 @@ VERSION: clean-local: rm -rf mo rpm -CLEANFILES = kimchi.spec `find "$(top_srcdir)" -type f -name "*.pyc" -print` +CLEANFILES = wok.spec `find "$(top_srcdir)" -type f -name "*.pyc" -print` diff --git a/VERSION b/VERSION index 26ca59460..bc80560fa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.1 +1.5.0 diff --git a/configure.ac b/configure.ac index cb7d5a203..fc4e1db10 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ # 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_INIT([wok], [m4_esyscmd([./build-aux/pkg-version --version])]) AC_SUBST([PACKAGE_VERSION], [m4_esyscmd([./build-aux/pkg-version --version])]) @@ -87,15 +87,13 @@ AC_CONFIG_FILES([ po/gen-pot Makefile docs/Makefile - docs/kimchid.8 + docs/wokd.8 src/Makefile - src/distros.d/Makefile src/nginx/Makefile - src/kimchi/Makefile - src/kimchi/control/Makefile - src/kimchi/control/vm/Makefile - src/kimchi/model/Makefile - src/kimchi/xmlutils/Makefile + src/wok/Makefile + src/wok/control/Makefile + src/wok/model/Makefile + src/wok/xmlutils/Makefile plugins/Makefile plugins/sample/Makefile plugins/sample/po/Makefile.in @@ -113,37 +111,17 @@ AC_CONFIG_FILES([ 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/libs/Makefile ui/libs/themes/Makefile ui/libs/themes/base/Makefile ui/libs/themes/base/images/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 - ui/pages/tabs/Makefile ui/pages/websockify/Makefile contrib/Makefile contrib/DEBIAN/Makefile contrib/DEBIAN/control - contrib/kimchi.spec.fedora - contrib/kimchi.spec.suse - tests/Makefile - config/Makefile - config/ui/Makefile + contrib/wok.spec.fedora + contrib/wok.spec.suse ],[ chmod +x po/gen-pot ]) diff --git a/contrib/DEBIAN/control.in b/contrib/DEBIAN/control.in index 1211f1fbc..ef4e0c236 100644 --- a/contrib/DEBIAN/control.in +++ b/contrib/DEBIAN/control.in @@ -6,32 +6,18 @@ Architecture: all Depends: python-cherrypy3 (>= 3.2.0), python-cheetah, python-imaging, - python-configobj, websockify, novnc, python-jsonschema (>= 1.3.0), - python-libvirt, gettext, - libvirt-bin, - nfs-common, python-m2crypto, - qemu-kvm, python-pam, - python-parted, - python-psutil (>= 0.6.0), - python-ethtool, - sosreport, - python-ipaddr, python-lxml, - open-iscsi, nginx, - python-guestfs, python-ldap, - libguestfs-tools, - spice-html5, - python-magic + spice-html5 Build-Depends: libxslt, openssl, python-lxml Maintainer: Aline Manera -Description: Kimchi web server +Description: Wok - Webserver Originated from Kimchi diff --git a/contrib/DEBIAN/postrm b/contrib/DEBIAN/postrm index ef90b493f..256a23482 100755 --- a/contrib/DEBIAN/postrm +++ b/contrib/DEBIAN/postrm @@ -20,9 +20,9 @@ case "$1" in remove) - rm -rf /var/log/kimchi /var/run/kimchi.pid + rm -rf /var/log/wok /var/run/wok.pid ;; purge) - rm -rf /var/log/kimchi /var/run/kimchi.pid /usr/share/kimchi/ + rm -rf /var/log/wok /var/run/wok.pid /usr/share/wok/ ;; esac diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 393306fac..b537df5c8 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -18,11 +18,11 @@ SUBDIRS = DEBIAN EXTRA_DIST = \ check_i18n.py \ - kimchid.sysvinit \ - kimchid.service.fedora \ - kimchi.spec.fedora.in \ - kimchid-upstart.conf.debian \ - kimchid-upstart.conf.fedora \ + wokd.sysvinit \ + wokd.service.fedora \ + wok.spec.fedora.in \ + wokd-upstart.conf.debian \ + wokd-upstart.conf.fedora \ make-deb.sh.in \ $(NULL) @@ -35,4 +35,4 @@ make-deb.sh: make-deb.sh.in $(top_builddir)/config.status mv $@-t $@ BUILT_SOURCES = make-deb.sh -CLEANFILES = kimchi.spec.fedora kimchi.spec.suse kimchi.spec make-deb.sh +CLEANFILES = wok.spec.fedora wok.spec.suse wok.spec make-deb.sh diff --git a/contrib/make-deb.sh.in b/contrib/make-deb.sh.in index 5a6e56a60..6c42072b6 100644 --- a/contrib/make-deb.sh.in +++ b/contrib/make-deb.sh.in @@ -11,5 +11,5 @@ fi TMPDIR=`mktemp -d` make DESTDIR=$TMPDIR install-deb -dpkg-deb -b $TMPDIR kimchi-${VERSION}-${RELEASE}.noarch.deb +dpkg-deb -b $TMPDIR wok-${VERSION}-${RELEASE}.noarch.deb rm -rf $TMPDIR diff --git a/contrib/wok.spec.fedora.in b/contrib/wok.spec.fedora.in new file mode 100644 index 000000000..30319a940 --- /dev/null +++ b/contrib/wok.spec.fedora.in @@ -0,0 +1,159 @@ +Name: wok +Version: @PACKAGE_VERSION@ +Release: @PACKAGE_RELEASE@%{?dist} +Summary: Wok - Webserver Originated from Kimchi +BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release} +BuildArch: noarch +Group: System Environment/Base +License: LGPL/ASL2 +Source0: %{name}-%{version}.tar.gz +Requires: gettext +Requires: python-cherrypy >= 3.2.0 +Requires: python-cheetah +Requires: python-websockify +Requires: novnc +Requires: m2crypto +Requires: python-imaging +Requires: PyPAM +Requires: python-jsonschema >= 1.3.0 +Requires: python-lxml +Requires: nginx +Requires: python-ldap +BuildRequires: libxslt +BuildRequires: openssl +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 + +%if 0%{?with_systemd} +Requires: systemd +Requires: firewalld +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +%endif + +%if 0%{?with_systemd} +BuildRequires: systemd-units +%endif + +%description +Wok is Webserver Originated from Kimchi. + + +%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 + +%if 0%{?rhel} == 6 +# Install the upstart script +install -Dm 0755 contrib/wokd-upstart.conf.fedora %{buildroot}/etc/init/wokd.conf +%endif +%if 0%{?rhel} == 5 +# Install the SysV init scripts +install -Dm 0755 contrib/wokd.sysvinit %{buildroot}%{_initrddir}/wokd +%endif + +%post +if [ $1 -eq 1 ] ; then + /bin/systemctl enable wokd.service >/dev/null 2>&1 || : + # Initial installation + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +fi + + +%preun + +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable wokd.service > /dev/null 2>&1 || : + /bin/systemctl stop wokd.service > /dev/null 2>&1 || : +fi + +exit 0 + + +%postun +if [ "$1" -ge 1 ] ; then + /bin/systemctl try-restart wokd.service >/dev/null 2>&1 || : +fi +exit 0 + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%attr(-,root,root) +%{_bindir}/wokd +%{python_sitelib}/wok/*.py* +%{python_sitelib}/wok/control/*.py* +%{python_sitelib}/wok/model/*.py* +%{python_sitelib}/wok/xmlutils/*.py* +%{python_sitelib}/wok/API.json +%{python_sitelib}/wok/plugins/*.py* +%{python_sitelib}/wok/ +%{_prefix}/share/locale/*/LC_MESSAGES/wok.mo +%{_datadir}/wok/ui/ +%{_datadir}/wok +%{_sysconfdir}/nginx/conf.d/wok.conf.in +%{_sysconfdir}/wok/wok.conf +%{_sysconfdir}/wok/ +%{_mandir}/man8/wokd.8.gz + +%if 0%{?with_systemd} +%{_sysconfdir}/nginx/conf.d/wok.conf +%{_sharedstatedir}/wok/vnc-tokens/ +%{_sharedstatedir}/wok/ +%{_localstatedir}/log/wok/* +%{_localstatedir}/log/wok/ +%{_unitdir}/wokd.service +%{_prefix}/lib/firewalld/services/wokd.xml +%endif +%if 0%{?rhel} == 6 +/etc/init/wokd.conf +%endif +%if 0%{?rhel} == 5 +%{_initrddir}/wokd +%endif + +%changelog +* Fri Jun 19 2015 Lucio Correia 1.6 +- Rename to wokd +- Remove kimchi specifics + +* Thu Feb 26 2015 Frédéric Bonnard 1.4.0 +- Add man page for kimchid + +* Tue Feb 11 2014 Crístian Viana 1.1.0 +- Add help pages and XSLT dependency + +* Tue Jul 16 2013 Adam Litke 0.1.0-1 +- Adapted for autotools build + +* Thu Apr 04 2013 Aline Manera 0.0-1 +- First build diff --git a/contrib/wok.spec.suse.in b/contrib/wok.spec.suse.in new file mode 100644 index 000000000..63bdce373 --- /dev/null +++ b/contrib/wok.spec.suse.in @@ -0,0 +1,133 @@ +Name: wok +Version: @PACKAGE_VERSION@ +Release: @PACKAGE_RELEASE@%{?dist} +Summary: Wok - Webserver Originated from Kimchi +BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release} +BuildArch: noarch +Group: System Environment/Base +License: LGPL/ASL2 +Source0: %{name}-%{version}.tar.gz +Requires: gettext-tools +Requires: python-CherryPy >= 3.2.0 +Requires: python-Cheetah +Requires: python-websockify +Requires: novnc +Requires: python-imaging +Requires: python-M2Crypto +Requires: python-pam +Requires: python-jsonschema >= 1.3.0 +Requires: python-ldap +Requires: python-lxml +Requires: python-xml +Requires: nginx +BuildRequires: libxslt-tools +BuildRequires: openssl +BuildRequires: python-lxml + +%if 0%{?suse_version} == 1100 +Requires: python-ordereddict +%endif + +%if 0%{?suse_version} > 1140 +%global with_systemd 1 +%endif + +%description +Wok is Webserver Originated from Kimchi. + +%prep +%setup + +%build +%configure --with-spice-html5 +make + +%install +rm -rf %{buildroot} +make DESTDIR=%{buildroot} install + + +%post +%if 0%{?with_systemd} + /bin/systemctl enable wokd.service >/dev/null 2>&1 || : + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +%else + chkconfig wokd on +%endif +exit 0 + + +%preun +%if 0%{?with_systemd} + /bin/systemctl --no-reload disable wokd.service > /dev/null 2>&1 || : + /bin/systemctl stop wokd.service > /dev/null 2>&1 || : +%else + service wokd stop +%endif +exit 0 + + +%postun +%if 0%{?with_systemd} + /bin/systemctl try-restart wokd.service >/dev/null 2>&1 || : +%endif +exit 0 + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%attr(-,root,root) +%{_bindir}/wokd +%{python_sitelib}/wok/*.py* +%{python_sitelib}/wok/control/*.py* +%{python_sitelib}/wok/model/*.py* +%{python_sitelib}/wok/xmlutils/*.py* +%{python_sitelib}/wok/API.json +%{python_sitelib}/wok/plugins/*.py* +%{python_sitelib}/wok/ +%{_prefix}/share/locale/*/LC_MESSAGES/wok.mo +%{_datadir}/wok/ui/ +%{_datadir}/wok +%{_sysconfdir}/wok/wok.conf +%{_sysconfdir}/wok/ +%{_sysconfdir}/nginx/conf.d/wok.conf.in +%{_sysconfdir}/nginx/conf.d/wok.conf +%{_var}/lib/wok/vnc-tokens/ +%{_var}/lib/wok/ +%{_localstatedir}/log/wok/* +%{_localstatedir}/log/wok/ +%{_mandir}/man8/wokd.8.gz + +%if 0%{?with_systemd} +%{_unitdir}/wokd.service +%else +%{_initrddir}/wokd +%endif + + + +%if 0%{?with_systemd} +%{_unitdir}/kimchid.service +%else +%{_initrddir}/kimchid +%endif + + +%changelog +* Fri Jun 19 2015 Lucio Correia 1.6 +- Rename to wokd +- Remove kimchi specifics + +* Thu Feb 26 2015 Frédéric Bonnard 1.4.0 +- Add man page for kimchid + +* Tue Feb 11 2014 Crístian Viana 1.1.0 +- Add help pages and XSLT dependency + +* Thu Jul 18 2013 Adam Litke 0.1.0-1 +- Adapted for autotools build +- Split Suse and Fedora spec files + +* Thu Apr 04 2013 Aline Manera 0.0-1 +- First build diff --git a/contrib/kimchid-upstart.conf.fedora b/contrib/wokd-upstart.conf.debian similarity index 79% rename from contrib/kimchid-upstart.conf.fedora rename to contrib/wokd-upstart.conf.debian index 53e8a39ca..82e915669 100644 --- a/contrib/kimchid-upstart.conf.fedora +++ b/contrib/wokd-upstart.conf.debian @@ -1,5 +1,5 @@ # -# kimchid - Kimchi Web Server +# wokd - Wok Web Server # # Copyright IBM, Corp. 2013 # @@ -18,16 +18,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # -description "Kimchi Web Server" +description "Wok - Webserver Originated from Kimchi" start on stopped rc RUNLEVEL=[2345] respawn respawn limit 5 30 -pre-start script - service libvirtd status | grep -q "start/running" && exit 0 - service libvirtd start || exit 1 -end script - -exec /usr/bin/kimchid +exec /usr/bin/wokd diff --git a/contrib/wokd-upstart.conf.fedora b/contrib/wokd-upstart.conf.fedora new file mode 100644 index 000000000..f02ce34eb --- /dev/null +++ b/contrib/wokd-upstart.conf.fedora @@ -0,0 +1,28 @@ +# +# wokd - Wok Web Server +# +# 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 +# + +description "Wok - Webserver Originated from Kimchi" + +start on stopped rc RUNLEVEL=[2345] + +respawn +respawn limit 5 30 + +exec /usr/bin/wokd diff --git a/contrib/kimchid.service.fedora b/contrib/wokd.service.fedora similarity index 58% rename from contrib/kimchid.service.fedora rename to contrib/wokd.service.fedora index 7abe49b03..17414d332 100644 --- a/contrib/kimchid.service.fedora +++ b/contrib/wokd.service.fedora @@ -1,13 +1,13 @@ [Unit] -Description=Kimchi server +Description=Wok - Webserver Originated from Kimchi Requires=libvirtd.service After=libvirtd.service [Service] Type=simple -ExecStart=/usr/bin/kimchid +ExecStart=/usr/bin/wokd ExecStop=/bin/kill -TERM $MAINPID -EnvironmentFile=/etc/kimchi/kimchi.conf +EnvironmentFile=/etc/wok/wok.conf [Install] WantedBy=multi-user.target diff --git a/contrib/kimchid.sysvinit b/contrib/wokd.sysvinit similarity index 89% rename from contrib/kimchid.sysvinit rename to contrib/wokd.sysvinit index 023b34c46..10680ee82 100644 --- a/contrib/kimchid.sysvinit +++ b/contrib/wokd.sysvinit @@ -1,6 +1,6 @@ #! /bin/sh # -# kimchid Kimchi Web Server +# wokd Wok Web Server # # Copyright IBM, Corp. 2013 # @@ -21,12 +21,12 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # ### BEGIN INIT INFO -# Provides: kimchid +# Provides: wokd # Required-Start: libvirtd # Required-Stop: # Default-Start: 3 5 # Default-Stop: 0 1 2 6 -# Description: Start the kimchid daemon +# Description: Start the wokd daemon ### END INIT INFO . /etc/rc.status @@ -45,21 +45,21 @@ rc_reset case "$1" in start) - echo -n "Starting kimchid daemon" + echo -n "Starting wokd daemon" ## Start daemon with startproc(8). If this fails ## the echo return value is set appropriate. - startproc -f /usr/bin/kimchid > /dev/null 2>&1 + startproc -f /usr/bin/wokd > /dev/null 2>&1 # Remember status and be verbose rc_status -v ;; stop) - echo -n "Shutting down kimchid daemon" + echo -n "Shutting down wokd daemon" ## Stop daemon with killproc(8) and if this fails ## set echo the echo return value. - killproc -TERM /usr/bin/kimchid + killproc -TERM /usr/bin/wokd # Remember status and be verbose rc_status -v @@ -82,7 +82,7 @@ case "$1" in rc_status ;; status) - echo -n "Checking for service kimchid " + echo -n "Checking for service wokd " ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. @@ -92,7 +92,7 @@ case "$1" in # 2 - service dead, but /var/lock/ lock file exists # 3 - service not running - checkproc /usr/bin/kimchid + checkproc /usr/bin/wokd rc_status -v ;; diff --git a/docs/API.md b/docs/API.md index a3a51c498..67d966e1d 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,10 +1,10 @@ -## Project Kimchi REST API Specification +## Wok 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 API provides 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: @@ -31,938 +31,10 @@ the following general conventions: 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 a '/' to indicate the root of the API. +* URIs begin with '/' to indicate Wok server root. * Variable segments in the URI begin with a ':' and should replaced with the appropriate resource identifier. -### Collection: Virtual Machines - -**URI:** /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:** /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:** /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:** /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:** /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:** /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:** /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:** /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:** /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:** /vms/*:name*/snapshots/current -* **GET**: Retrieve current snapshot information for the virtual machine. - -### Collection: Templates - -**URI:** /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:** /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:** /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. - * ips: A list of IP addresses associated with this MAC. - * 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:** /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:** /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:** /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:** /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:** /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. - * isvalid: True if is a valid 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:** /interfaces - -**Methods:** - -* **GET**: Retrieve a summarized list of current Interfaces - -### Resource: Interface - -**URI:** /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:** /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:** /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 - - -### Collection: Tasks - -**URI:** /tasks - -**Methods:** - -* **GET**: Retrieve a summarized list of current Tasks - -### Resource: Task - -**URI:** /tasks/*:id* - -A task represents an asynchronous operation that is being performed by the -server. - -**Methods:** - -* **GET**: Retrieve the full description of the Task - * id: The Task ID is used to identify this Task in the API. - * status: The current status of the Task - * running: The task is running - * finished: The task has finished successfully - * failed: The task failed - * message: Human-readable details about the Task status - * target_uri: Resource URI related to the Task -* **POST**: *See Task Actions* - -**Actions (POST):** - -*No actions defined* - -### Resource: Configuration - -**URI:** /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:** /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:** /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:** /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:** /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:** /config/distros - -**Methods:** - -* **GET**: Retrieve a summarized list of all Distros - -### Resource: Distro - -**URI:** /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:** /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:** /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:** /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:** /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:** /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:** /groups -List of available groups. - -**Methods:** - -* **GET**: Retrieve list of available groups, only support 'pam' authentication. - -### Resource: HostStats - -**URI:** /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:** /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:** /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: Plugins @@ -972,190 +44,3 @@ stats history * **GET**: Retrieve a summarized list names of all UI Plugins -### Collection: Partitions - -**URI:** /host/partitions - -**Methods:** - -* **GET**: Retrieves a detailed list of all partitions of the host. - -### Resource: Partition - -**URI:** /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:** /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. - * _available_only: Filter to list only the host devices that are not - attached to a VM. - -### Resource: Device - -**URI:** /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:** /host/devices/*:name*/vmholders -* **GET**: Retrieve a summarized list of all VMs holding the device. - -### Sub-resource: VM holder -**URI:** /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:** /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:** /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:** /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:** /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. - * display_repo_name: The same name retrieve from repo_name with any - possible variable expanded. - * 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:** /peers - -**Methods:** - -* **GET**: Return the list of Kimchi peers in the same network - (It uses openSLP for discovering) diff --git a/docs/Makefile.am b/docs/Makefile.am index 2f686f1c9..db237213c 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -17,15 +17,12 @@ # 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 +docdir = $(datadir)/wok/doc dist_doc_DATA = \ API.md \ README.md \ - README-federation.md \ - kimchi-guest.png \ - kimchi-templates.png \ - kimchid.8 \ + wokd.8 \ $(NULL) -CLEANFILES = kimchid.8 +CLEANFILES = wokd.8 diff --git a/docs/README.md b/docs/README.md index 541b4c89f..1b31ccf76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,147 +1,32 @@ -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 daemon on the hypervisor host. It 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 daemon 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 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 python-magic - - # 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_packages.3F) -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 python-magic - - 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 python-magic - - 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, [this FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewalk/) -for python-ethtool, and [this FAQ](http://download.opensuse.org/repositories/home:/Simmphonie:/python/) for python-magic 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. +Wok (Webserver Originated from Kimchi) +====================================== + +Wok is a cherrypy-based web framework with HTML5 support that is extended by +plugins which expose functionality through REST APIs. + +Examples of such plugins are Kimchi (Virtualization Management) and Ginger +(System Administration). Wok comes with a sample plugin for education purposes. + +Wok runs through wokd daemon. + Build and Install ----------------- - 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 kimchid --host=0.0.0.0 + $ sudo wokd --host=0.0.0.0 -If you cannot access Kimchi, take a look at these 2 points: +If you cannot access Wok, take a look at these 2 points: 1. Firewall -Kimchi uses by default the ports 8000, 8001 and 64667. To allow incoming connections: +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 @@ -163,65 +48,11 @@ Kimchi uses by default the ports 8000, 8001 and 64667. To allow incoming connect 2. SELinux -Allow httpd_t context for Kimchi web server: +Allow httpd_t context for Wok web server: semanage permissive -a httpd_t -Test ----- - - $ 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: - -![Kimchi Login Screen](/docs/kimchi-login.png) - -Kimchi 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=, anonuid=,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 ------------- diff --git a/docs/kimchid.8.in b/docs/wokd.8.in similarity index 100% rename from docs/kimchid.8.in rename to docs/wokd.8.in diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 894d28e2e..21a6ece6d 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -22,4 +22,4 @@ SUBDIRS = sample plugins_PYTHON = \ __init__.py -pluginsdir = $(pythondir)/kimchi/plugins +pluginsdir = $(pythondir)/wok/plugins diff --git a/plugins/kimchi/.gitignore b/plugins/kimchi/.gitignore new file mode 100644 index 000000000..1dae610fc --- /dev/null +++ b/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/kimchi/API.json b/plugins/kimchi/API.json similarity index 98% rename from src/kimchi/API.json rename to plugins/kimchi/API.json index c7ea660d5..fc1d2dd55 100644 --- a/src/kimchi/API.json +++ b/plugins/kimchi/API.json @@ -257,14 +257,14 @@ "template": { "description": "The URI of a template to use when building a VM", "type": "string", - "pattern": "^/templates/(.*?)/?$", + "pattern": "^/plugins/kimchi/templates/(.*?)/?$", "required": true, "error": "KCHVM0012E" }, "storagepool": { "description": "Assign a specefic Storage Pool to the new VM", "type": "string", - "pattern": "^/storagepools/[^/]+/?$", + "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$", "error": "KCHVM0013E" }, "graphics": { "$ref": "#/kimchitype/graphics" } @@ -428,7 +428,7 @@ "icon": { "description": "The template icon path", "type": "string", - "pattern": "^images/", + "pattern": "^/plugins/kimchi/images/", "error": "KCHTMPL0009E" }, "os_distro": { @@ -493,7 +493,7 @@ "storagepool": { "description": "Location of the storage pool", "type": "string", - "pattern": "^/storagepools/[^/]+/?$", + "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$", "error": "KCHTMPL0015E" }, "networks": { @@ -600,7 +600,7 @@ "icon": { "description": "The template icon path", "type": "string", - "pattern": "^images/", + "pattern": "^/plugins/kimchi/images/", "error": "KCHTMPL0009E" }, "os_distro": { @@ -664,7 +664,7 @@ "storagepool": { "description": "Location of the storage pool", "type": "string", - "pattern": "^/storagepools/[^/]+/?$", + "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$", "error": "KCHTMPL0015E" }, "networks": { diff --git a/plugins/kimchi/INSTALL b/plugins/kimchi/INSTALL new file mode 100644 index 000000000..63bf0760e --- /dev/null +++ b/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 `' 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 new file mode 100644 index 000000000..faef341ad --- /dev/null +++ b/plugins/kimchi/Makefile.am @@ -0,0 +1,159 @@ +# +# 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/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/{debugreports,screenshots,isos} + +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 new file mode 120000 index 000000000..0e01b4308 --- /dev/null +++ b/plugins/kimchi/README.md @@ -0,0 +1 @@ +docs/README.md \ No newline at end of file diff --git a/plugins/kimchi/VERSION b/plugins/kimchi/VERSION new file mode 100644 index 000000000..26ca59460 --- /dev/null +++ b/plugins/kimchi/VERSION @@ -0,0 +1 @@ +1.5.1 diff --git a/plugins/kimchi/__init__.py b/plugins/kimchi/__init__.py new file mode 100644 index 000000000..933004462 --- /dev/null +++ b/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/plugins/kimchi/autogen.sh b/plugins/kimchi/autogen.sh new file mode 100755 index 000000000..0f22dba0d --- /dev/null +++ b/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/plugins/kimchi/build-aux/config.rpath b/plugins/kimchi/build-aux/config.rpath new file mode 100644 index 000000000..17298f234 --- /dev/null +++ b/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 , 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 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=/' < 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 new file mode 100644 index 000000000..4b82e45ee --- /dev/null +++ b/plugins/kimchi/config.py.in @@ -0,0 +1,138 @@ +# +# 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 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') + + custom_config = { + '/novnc': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': kimchiPaths.novnc_dir, + 'tools.nocache.on': True, + 'tools.wokauth.on': True, + }, + + '/spice_auto.html': { + 'tools.staticfile.on': True, + 'tools.staticfile.filename': kimchiPaths.spice_file, + 'tools.nocache.on': True, + 'tools.wokauth.on': True, + }, + + '/spice-html5': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': kimchiPaths.spice_dir, + 'tools.nocache.on': True, + }, + + '/spice-html5/spice.css': { + 'tools.staticfile.on': True, + 'tools.staticfile.filename': kimchiPaths.spice_css_file, + 'tools.nocache.on': True, + }, + } + + self.update(custom_config) diff --git a/plugins/kimchi/config.rpath b/plugins/kimchi/config.rpath new file mode 100644 index 000000000..17298f234 --- /dev/null +++ b/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 , 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 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=/' <@] + )], + , + [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 new file mode 100644 index 000000000..ca89552f3 --- /dev/null +++ b/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/plugins/kimchi/contrib/DEBIAN/control.in b/plugins/kimchi/contrib/DEBIAN/control.in new file mode 100644 index 000000000..47de44f5d --- /dev/null +++ b/plugins/kimchi/contrib/DEBIAN/control.in @@ -0,0 +1,37 @@ +Package: @PACKAGE_NAME@ +Version: @PACKAGE_VERSION@ +Section: base +Priority: optional +Architecture: all +Depends: wok, + python-cherrypy3 (>= 3.2.0), + python-cheetah, + python-imaging, + python-configobj, + websockify, + novnc, + python-jsonschema (>= 1.3.0), + python-libvirt, + gettext, + libvirt-bin, + nfs-common, + python-m2crypto, + qemu-kvm, + python-pam, + python-parted, + python-psutil (>= 0.6.0), + python-ethtool, + sosreport, + python-ipaddr, + python-lxml, + open-iscsi, + nginx, + python-guestfs, + python-ldap, + libguestfs-tools, + spice-html5, + python-magic +Build-Depends: libxslt, + python-lxml +Maintainer: Aline Manera +Description: Kimchi web application diff --git a/contrib/kimchid-upstart.conf.debian b/plugins/kimchi/contrib/Makefile.am similarity index 59% rename from contrib/kimchid-upstart.conf.debian rename to plugins/kimchi/contrib/Makefile.am index a58d3c3ae..500119104 100644 --- a/contrib/kimchid-upstart.conf.debian +++ b/plugins/kimchi/contrib/Makefile.am @@ -1,7 +1,4 @@ -# -# kimchid - Kimchi Web Server -# -# Copyright IBM, Corp. 2013 +# 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 @@ -16,19 +13,22 @@ # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -# - -description "Kimchi Web Server" -start on started libvirt-bin -stop on stopped libvirt-bin +SUBDIRS = DEBIAN -respawn -respawn limit 5 30 +EXTRA_DIST = \ + check_i18n.py \ + kimchi.spec.fedora.in \ + make-deb.sh.in \ + $(NULL) -pre-start script - status libvirt-bin | grep -q "start/running" && exit 0 - start libvirt-bin || exit 1 -end script +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 -exec /usr/bin/kimchid +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 new file mode 100755 index 000000000..6a2603c92 --- /dev/null +++ b/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/contrib/kimchi.spec.fedora.in b/plugins/kimchi/contrib/kimchi.spec.fedora.in similarity index 55% rename from contrib/kimchi.spec.fedora.in rename to plugins/kimchi/contrib/kimchi.spec.fedora.in index 8463930d8..f555bdeae 100644 --- a/contrib/kimchi.spec.fedora.in +++ b/plugins/kimchi/contrib/kimchi.spec.fedora.in @@ -7,8 +7,9 @@ BuildArch: noarch Group: System Environment/Base License: LGPL/ASL2 Source0: %{name}-%{version}.tar.gz +Requires: wok Requires: qemu-kvm -Requires: gettext-devel +Requires: gettext Requires: libvirt Requires: libvirt-python Requires: libvirt-daemon-config-network @@ -35,7 +36,6 @@ Requires: python-libguestfs Requires: libguestfs-tools Requires: python-magic BuildRequires: libxslt -BuildRequires: openssl BuildRequires: python-lxml %if 0%{?rhel} >= 6 || 0%{?fedora} >= 19 @@ -52,20 +52,8 @@ Requires: python-imaging BuildRequires: python-unittest2 %endif -%if 0%{?with_systemd} -Requires: systemd -Requires: firewalld -Requires(post): systemd -Requires(preun): systemd -Requires(postun): systemd -%endif - -%if 0%{?with_systemd} -BuildRequires: systemd-units -%endif - %description -Web server application to manage KVM/Qemu virtual machines +Web application to manage KVM/Qemu virtual machines %prep @@ -85,71 +73,29 @@ make rm -rf %{buildroot} make DESTDIR=%{buildroot} install -%if 0%{?with_systemd} - -%endif - -%if 0%{?rhel} == 6 -# Install the upstart script -install -Dm 0755 contrib/kimchid-upstart.conf.fedora %{buildroot}/etc/init/kimchid.conf -%endif -%if 0%{?rhel} == 5 -# Install the SysV init scripts -install -Dm 0755 contrib/kimchid.sysvinit %{buildroot}%{_initrddir}/kimchid -%endif - -%post -if [ $1 -eq 1 ] ; then - /bin/systemctl enable kimchid.service >/dev/null 2>&1 || : - # Initial installation - /bin/systemctl daemon-reload >/dev/null 2>&1 || : -fi - - -%preun - -if [ $1 -eq 0 ] ; then - # Package removal, not upgrade - /bin/systemctl --no-reload disable kimchid.service > /dev/null 2>&1 || : - /bin/systemctl stop kimchid.service > /dev/null 2>&1 || : -fi - -exit 0 - - -%postun -if [ "$1" -ge 1 ] ; then - /bin/systemctl try-restart kimchid.service >/dev/null 2>&1 || : -fi -exit 0 %clean rm -rf $RPM_BUILD_ROOT %files %attr(-,root,root) -%{_bindir}/kimchid -%{python_sitelib}/kimchi/*.py* -%{python_sitelib}/kimchi/control/*.py* -%{python_sitelib}/kimchi/control/vm/*.py* -%{python_sitelib}/kimchi/model/*.py* -%{python_sitelib}/kimchi/xmlutils/*.py* -%{python_sitelib}/kimchi/API.json -%{python_sitelib}/kimchi/plugins/*.py* -%{python_sitelib}/kimchi/ +%{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}/kimchi/config/ui/*.xml -%{_datadir}/kimchi/ui/ -%{_datadir}/kimchi -%{_sysconfdir}/nginx/conf.d/kimchi.conf.in -%{_sysconfdir}/nginx/conf.d/kimchi.conf -%{_sysconfdir}/kimchi/kimchi.conf -%{_sysconfdir}/kimchi/template.conf +%{_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 @@ -158,25 +104,14 @@ rm -rf $RPM_BUILD_ROOT %{_sysconfdir}/kimchi/ %{_sharedstatedir}/kimchi/debugreports/ %{_sharedstatedir}/kimchi/screenshots/ -%{_sharedstatedir}/kimchi/vnc-tokens/ %{_sharedstatedir}/kimchi/isos/ %{_sharedstatedir}/kimchi/ -%{_localstatedir}/log/kimchi/* -%{_localstatedir}/log/kimchi/ -%{_mandir}/man8/kimchid.8.gz -%if 0%{?with_systemd} -%{_unitdir}/kimchid.service -%{_prefix}/lib/firewalld/services/kimchid.xml -%endif -%if 0%{?rhel} == 6 -/etc/init/kimchid.conf -%endif -%if 0%{?rhel} == 5 -%{_initrddir}/kimchid -%endif %changelog +* Thu Jun 18 2015 Lucio Correia 1.6 +- Run kimchi as a plugin + * Thu Feb 26 2015 Frédéric Bonnard 1.4.0 - Add man page for kimchid diff --git a/contrib/kimchi.spec.suse.in b/plugins/kimchi/contrib/kimchi.spec.suse.in similarity index 63% rename from contrib/kimchi.spec.suse.in rename to plugins/kimchi/contrib/kimchi.spec.suse.in index b6f00d4ee..9ee8d1301 100644 --- a/contrib/kimchi.spec.suse.in +++ b/plugins/kimchi/contrib/kimchi.spec.suse.in @@ -7,6 +7,7 @@ BuildArch: noarch Group: System Environment/Base License: LGPL/ASL2 Source0: %{name}-%{version}.tar.gz +Requires: wok Requires: kvm Requires: gettext-tools Requires: libvirt @@ -35,7 +36,6 @@ Requires: python-libguestfs Requires: guestfs-tools Requires: python-magic BuildRequires: libxslt-tools -BuildRequires: openssl BuildRequires: python-lxml %if 0%{?suse_version} == 1100 @@ -47,7 +47,7 @@ Requires: python-ordereddict %endif %description -Web server application to manage KVM/Qemu virtual machines +Web application to manage KVM/Qemu virtual machines %prep %setup @@ -60,83 +60,46 @@ make rm -rf %{buildroot} make DESTDIR=%{buildroot} install -%post -%if 0%{?with_systemd} - /bin/systemctl enable kimchid.service >/dev/null 2>&1 || : - /bin/systemctl daemon-reload >/dev/null 2>&1 || : -%else - chkconfig kimchid on -%endif -exit 0 - - -%preun -%if 0%{?with_systemd} - /bin/systemctl --no-reload disable kimchid.service > /dev/null 2>&1 || : - /bin/systemctl stop kimchid.service > /dev/null 2>&1 || : -%else - service kimchid stop -%endif -exit 0 - - -%postun -%if 0%{?with_systemd} - /bin/systemctl try-restart kimchid.service >/dev/null 2>&1 || : -%endif -exit 0 %clean rm -rf $RPM_BUILD_ROOT %files %attr(-,root,root) -%{_bindir}/kimchid -%{python_sitelib}/kimchi/*.py* -%{python_sitelib}/kimchi/control/*.py* -%{python_sitelib}/kimchi/control/vm/*.py* -%{python_sitelib}/kimchi/model/*.py* -%{python_sitelib}/kimchi/xmlutils/*.py* -%{python_sitelib}/kimchi/API.json -%{python_sitelib}/kimchi/plugins/*.py* -%{python_sitelib}/kimchi/ +%{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}/kimchi/config/ui/*.xml -%{_datadir}/kimchi/ui/ -%{_datadir}/kimchi -%{_sysconfdir}/nginx/conf.d/kimchi.conf.in -%{_sysconfdir}/nginx/conf.d/kimchi.conf -%{_sysconfdir}/kimchi/kimchi.conf -%{_sysconfdir}/kimchi/template.conf +%{_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 %{_sysconfdir}/kimchi/ %{_var}/lib/kimchi/debugreports/ %{_var}/lib/kimchi/screenshots/ -%{_var}/lib/kimchi/vnc-tokens/ %{_var}/lib/kimchi/isos/ %{_var}/lib/kimchi/ -%{_localstatedir}/log/kimchi/* -%{_localstatedir}/log/kimchi/ -%{_mandir}/man8/kimchid.8.gz - -%if 0%{?with_systemd} -%{_unitdir}/kimchid.service -%else -%{_initrddir}/kimchid -%endif + %changelog +* Thu Jun 18 2015 Lucio Correia 1.6 +- Run kimchi as a plugin + * Thu Feb 26 2015 Frédéric Bonnard 1.4.0 - Add man page for kimchid diff --git a/plugins/kimchi/contrib/make-deb.sh.in b/plugins/kimchi/contrib/make-deb.sh.in new file mode 100644 index 000000000..5a6e56a60 --- /dev/null +++ b/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/kimchi/control/Makefile.am b/plugins/kimchi/control/Makefile.am similarity index 94% rename from src/kimchi/control/Makefile.am rename to plugins/kimchi/control/Makefile.am index fee98dc32..33118ca94 100644 --- a/src/kimchi/control/Makefile.am +++ b/plugins/kimchi/control/Makefile.am @@ -21,7 +21,7 @@ SUBDIRS = vm control_PYTHON = *.py -controldir = $(pythondir)/kimchi/control +controldir = $(pythondir)/wok/plugins/kimchi/control install-data-local: $(MKDIR_P) $(DESTDIR)$(controldir) diff --git a/src/kimchi/control/__init__.py b/plugins/kimchi/control/__init__.py similarity index 94% rename from src/kimchi/control/__init__.py rename to plugins/kimchi/control/__init__.py index 98d42d3a3..4ad945978 100644 --- a/src/kimchi/control/__init__.py +++ b/plugins/kimchi/control/__init__.py @@ -20,7 +20,7 @@ import os -from kimchi.control.utils import load_url_sub_node +from wok.control.utils import load_url_sub_node sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__) diff --git a/src/kimchi/control/config.py b/plugins/kimchi/control/config.py similarity index 94% rename from src/kimchi/control/config.py rename to plugins/kimchi/control/config.py index 45bb01329..15df68f35 100644 --- a/src/kimchi/control/config.py +++ b/plugins/kimchi/control/config.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode("config") diff --git a/src/kimchi/control/cpuinfo.py b/plugins/kimchi/control/cpuinfo.py similarity index 96% rename from src/kimchi/control/cpuinfo.py rename to plugins/kimchi/control/cpuinfo.py index 415dd3dd5..31f316c41 100644 --- a/src/kimchi/control/cpuinfo.py +++ b/plugins/kimchi/control/cpuinfo.py @@ -18,7 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -from kimchi.control.base import Resource +from wok.control.base import Resource class CPUInfo(Resource): diff --git a/src/kimchi/control/debugreports.py b/plugins/kimchi/control/debugreports.py similarity index 92% rename from src/kimchi/control/debugreports.py rename to plugins/kimchi/control/debugreports.py index 377d00272..b5a3072ce 100644 --- a/src/kimchi/control/debugreports.py +++ b/plugins/kimchi/control/debugreports.py @@ -17,9 +17,9 @@ # 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 kimchi.control.base import AsyncCollection, Resource -from kimchi.control.utils import internal_redirect -from kimchi.control.utils import UrlSubNode +from wok.control.base import AsyncCollection, Resource +from wok.control.utils import internal_redirect +from wok.control.utils import UrlSubNode @UrlSubNode('debugreports', True) diff --git a/src/kimchi/control/groups.py b/plugins/kimchi/control/groups.py similarity index 91% rename from src/kimchi/control/groups.py rename to plugins/kimchi/control/groups.py index f18b2ab16..649ff0936 100644 --- a/src/kimchi/control/groups.py +++ b/plugins/kimchi/control/groups.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import SimpleCollection -from kimchi.control.utils import UrlSubNode +from wok.control.base import SimpleCollection +from wok.control.utils import UrlSubNode @UrlSubNode('groups', True) diff --git a/src/kimchi/control/host.py b/plugins/kimchi/control/host.py similarity index 95% rename from src/kimchi/control/host.py rename to plugins/kimchi/control/host.py index 5e736dbd5..0a40f1bfa 100644 --- a/src/kimchi/control/host.py +++ b/plugins/kimchi/control/host.py @@ -17,10 +17,11 @@ # 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 kimchi.control.cpuinfo import CPUInfo -from kimchi.control.base import Collection, Resource, SimpleCollection -from kimchi.control.utils import UrlSubNode -from kimchi.exception import NotFoundError +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) diff --git a/src/kimchi/control/interfaces.py b/plugins/kimchi/control/interfaces.py similarity index 94% rename from src/kimchi/control/interfaces.py rename to plugins/kimchi/control/interfaces.py index 3c76f3fbf..d698b7a52 100644 --- a/src/kimchi/control/interfaces.py +++ b/plugins/kimchi/control/interfaces.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode('interfaces', True) diff --git a/src/kimchi/control/networks.py b/plugins/kimchi/control/networks.py similarity index 95% rename from src/kimchi/control/networks.py rename to plugins/kimchi/control/networks.py index 42e013fb2..fd92111f5 100644 --- a/src/kimchi/control/networks.py +++ b/plugins/kimchi/control/networks.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode('networks', True) diff --git a/src/kimchi/control/peers.py b/plugins/kimchi/control/peers.py similarity index 91% rename from src/kimchi/control/peers.py rename to plugins/kimchi/control/peers.py index f72a38cb3..21e9f1356 100644 --- a/src/kimchi/control/peers.py +++ b/plugins/kimchi/control/peers.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import SimpleCollection -from kimchi.control.utils import UrlSubNode +from wok.control.base import SimpleCollection +from wok.control.utils import UrlSubNode @UrlSubNode("peers", True) diff --git a/src/kimchi/control/storagepools.py b/plugins/kimchi/control/storagepools.py similarity index 91% rename from src/kimchi/control/storagepools.py rename to plugins/kimchi/control/storagepools.py index ee74beee3..e5f264e8a 100644 --- a/src/kimchi/control/storagepools.py +++ b/plugins/kimchi/control/storagepools.py @@ -19,12 +19,13 @@ import cherrypy -from kimchi.control.base import Collection, Resource -from kimchi.control.storagevolumes import IsoVolumes, StorageVolumes -from kimchi.control.utils import get_class_name, model_fn -from kimchi.control.utils import validate_params -from kimchi.model.storagepools import ISO_POOL_NAME -from kimchi.control.utils import UrlSubNode +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) diff --git a/src/kimchi/control/storageservers.py b/plugins/kimchi/control/storageservers.py similarity index 89% rename from src/kimchi/control/storageservers.py rename to plugins/kimchi/control/storageservers.py index 4b70c3901..654ab4733 100644 --- a/src/kimchi/control/storageservers.py +++ b/plugins/kimchi/control/storageservers.py @@ -17,9 +17,9 @@ # 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 kimchi.template -from kimchi.control.base import Collection, Resource -from kimchi.control.utils import get_class_name, model_fn, UrlSubNode +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) @@ -57,4 +57,4 @@ 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 kimchi.template.render(get_class_name(self), res_list) + return template.render(get_class_name(self), res_list) diff --git a/src/kimchi/control/storagevolumes.py b/plugins/kimchi/control/storagevolumes.py similarity index 92% rename from src/kimchi/control/storagevolumes.py rename to plugins/kimchi/control/storagevolumes.py index d3532f611..f920deed3 100644 --- a/src/kimchi/control/storagevolumes.py +++ b/plugins/kimchi/control/storagevolumes.py @@ -17,9 +17,9 @@ # 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 kimchi.template -from kimchi.control.base import AsyncCollection, Collection, Resource -from kimchi.control.utils import get_class_name, model_fn +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): @@ -81,4 +81,4 @@ def get(self, filter_params): except AttributeError: pass - return kimchi.template.render(get_class_name(self), res_list) + return template.render(get_class_name(self), res_list) diff --git a/src/kimchi/control/tasks.py b/plugins/kimchi/control/tasks.py similarity index 91% rename from src/kimchi/control/tasks.py rename to plugins/kimchi/control/tasks.py index 4870dbd11..b25d89203 100644 --- a/src/kimchi/control/tasks.py +++ b/plugins/kimchi/control/tasks.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode("tasks", True) diff --git a/src/kimchi/control/templates.py b/plugins/kimchi/control/templates.py similarity index 95% rename from src/kimchi/control/templates.py rename to plugins/kimchi/control/templates.py index 4c459103e..fc5881542 100644 --- a/src/kimchi/control/templates.py +++ b/plugins/kimchi/control/templates.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode('templates', True) diff --git a/src/kimchi/control/users.py b/plugins/kimchi/control/users.py similarity index 88% rename from src/kimchi/control/users.py rename to plugins/kimchi/control/users.py index 45603d02f..756a2f756 100644 --- a/src/kimchi/control/users.py +++ b/plugins/kimchi/control/users.py @@ -17,9 +17,9 @@ # 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 kimchi.control.base import SimpleCollection -from kimchi.control.utils import get_class_name, model_fn, UrlSubNode -from kimchi.template import render +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) diff --git a/src/kimchi/control/vm/Makefile.am b/plugins/kimchi/control/vm/Makefile.am similarity index 94% rename from src/kimchi/control/vm/Makefile.am rename to plugins/kimchi/control/vm/Makefile.am index e57b90793..b17c68a16 100644 --- a/src/kimchi/control/vm/Makefile.am +++ b/plugins/kimchi/control/vm/Makefile.am @@ -20,7 +20,7 @@ vm_PYTHON = *.py -vmdir = $(pythondir)/kimchi/control/vm +vmdir = $(pythondir)/wok/plugins/kimchi/control/vm install-data-local: $(MKDIR_P) $(DESTDIR)$(vmdir) diff --git a/src/kimchi/control/vm/__init__.py b/plugins/kimchi/control/vm/__init__.py similarity index 94% rename from src/kimchi/control/vm/__init__.py rename to plugins/kimchi/control/vm/__init__.py index 2ea1e8c7a..a3110459b 100644 --- a/src/kimchi/control/vm/__init__.py +++ b/plugins/kimchi/control/vm/__init__.py @@ -20,7 +20,7 @@ import os -from kimchi.control.utils import load_url_sub_node +from wok.control.utils import load_url_sub_node sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__) diff --git a/src/kimchi/control/vm/hostdevs.py b/plugins/kimchi/control/vm/hostdevs.py similarity index 93% rename from src/kimchi/control/vm/hostdevs.py rename to plugins/kimchi/control/vm/hostdevs.py index 1eb88cf3a..a43b9d86b 100644 --- a/src/kimchi/control/vm/hostdevs.py +++ b/plugins/kimchi/control/vm/hostdevs.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode("hostdevs") diff --git a/src/kimchi/control/vm/ifaces.py b/plugins/kimchi/control/vm/ifaces.py similarity index 93% rename from src/kimchi/control/vm/ifaces.py rename to plugins/kimchi/control/vm/ifaces.py index 8a6021704..ac957fd1d 100644 --- a/src/kimchi/control/vm/ifaces.py +++ b/plugins/kimchi/control/vm/ifaces.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode("ifaces") diff --git a/src/kimchi/control/vm/snapshots.py b/plugins/kimchi/control/vm/snapshots.py similarity index 94% rename from src/kimchi/control/vm/snapshots.py rename to plugins/kimchi/control/vm/snapshots.py index bbebc9a8f..dd17b8582 100644 --- a/src/kimchi/control/vm/snapshots.py +++ b/plugins/kimchi/control/vm/snapshots.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import AsyncCollection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import AsyncCollection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode('snapshots') diff --git a/src/kimchi/control/vm/storages.py b/plugins/kimchi/control/vm/storages.py similarity index 93% rename from src/kimchi/control/vm/storages.py rename to plugins/kimchi/control/vm/storages.py index 81a5d486f..f502caab8 100644 --- a/src/kimchi/control/vm/storages.py +++ b/plugins/kimchi/control/vm/storages.py @@ -17,8 +17,8 @@ # 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 kimchi.control.base import Collection, Resource -from kimchi.control.utils import UrlSubNode +from wok.control.base import Collection, Resource +from wok.control.utils import UrlSubNode @UrlSubNode("storages") diff --git a/src/kimchi/control/vms.py b/plugins/kimchi/control/vms.py similarity index 93% rename from src/kimchi/control/vms.py rename to plugins/kimchi/control/vms.py index a40b56e7a..858b23c8d 100644 --- a/src/kimchi/control/vms.py +++ b/plugins/kimchi/control/vms.py @@ -17,9 +17,10 @@ # 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 kimchi.control.base import AsyncCollection, Resource -from kimchi.control.utils import internal_redirect, UrlSubNode -from kimchi.control.vm import sub_nodes +from wok.control.base import AsyncCollection, Resource +from wok.control.utils import internal_redirect, UrlSubNode + +from vm import sub_nodes @UrlSubNode('vms', True) diff --git a/src/kimchi/disks.py b/plugins/kimchi/disks.py similarity index 97% rename from src/kimchi/disks.py rename to plugins/kimchi/disks.py index 016a07943..eb40e3a72 100644 --- a/src/kimchi/disks.py +++ b/plugins/kimchi/disks.py @@ -20,12 +20,11 @@ import os.path import re import subprocess - from parted import Device as PDevice from parted import Disk as PDisk -from kimchi.exception import OperationFailed -from kimchi.utils import kimchi_log +from wok.exception import OperationFailed +from wok.utils import wok_log def _get_dev_node_path(maj_min): @@ -82,7 +81,7 @@ def _is_dev_leaf(devNodePath): except OperationFailed as e: # lsblk is known to fail on multipath devices # Assume these devices contain children - kimchi_log.error( + wok_log.error( "Error getting device info for %s: %s", devNodePath, e) return False @@ -97,7 +96,7 @@ def _is_dev_extended_partition(devType, devNodePath): try: extended_part = PDisk(device).getExtendedPartition() except NotImplementedError as e: - kimchi_log.warning( + 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 @@ -180,7 +179,7 @@ def get_partition_details(name): try: dev = _get_lsblk_devs(keys, [dev_path])[0] except OperationFailed as e: - kimchi_log.error( + wok_log.error( "Error getting partition info for %s: %s", name, e) return {} diff --git a/src/kimchi/distroloader.py b/plugins/kimchi/distroloader.py similarity index 91% rename from src/kimchi/distroloader.py rename to plugins/kimchi/distroloader.py index daed73c7b..00327372e 100644 --- a/src/kimchi/distroloader.py +++ b/plugins/kimchi/distroloader.py @@ -23,9 +23,10 @@ import os -from kimchi import config -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.utils import kimchi_log +from wok.exception import NotFoundError, OperationFailed +from wok.utils import wok_log + +import config ARCHS = {'x86_64': ['x86_64', 'amd64', 'i686', 'x86', 'i386'], @@ -43,7 +44,7 @@ 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 - kimchi_log.error(msg) + wok_log.error(msg) raise NotFoundError("KCHDL0001E", msg_args) try: with open(fname) as f: @@ -51,7 +52,7 @@ def _get_json_info(self, fname): return data except ValueError: msg = "DistroLoader: failed to parse distro file: %s" % fname - kimchi_log.error(msg) + wok_log.error(msg) raise OperationFailed("KCHDL0002E", msg_args) def get(self): diff --git a/src/distros.d/Makefile.am b/plugins/kimchi/distros.d/Makefile.am similarity index 100% rename from src/distros.d/Makefile.am rename to plugins/kimchi/distros.d/Makefile.am diff --git a/src/distros.d/debian.json b/plugins/kimchi/distros.d/debian.json similarity index 100% rename from src/distros.d/debian.json rename to plugins/kimchi/distros.d/debian.json diff --git a/src/distros.d/fedora.json b/plugins/kimchi/distros.d/fedora.json similarity index 100% rename from src/distros.d/fedora.json rename to plugins/kimchi/distros.d/fedora.json diff --git a/src/distros.d/gentoo.json b/plugins/kimchi/distros.d/gentoo.json similarity index 100% rename from src/distros.d/gentoo.json rename to plugins/kimchi/distros.d/gentoo.json diff --git a/src/distros.d/opensuse.json b/plugins/kimchi/distros.d/opensuse.json similarity index 100% rename from src/distros.d/opensuse.json rename to plugins/kimchi/distros.d/opensuse.json diff --git a/src/distros.d/ubuntu.json b/plugins/kimchi/distros.d/ubuntu.json similarity index 100% rename from src/distros.d/ubuntu.json rename to plugins/kimchi/distros.d/ubuntu.json diff --git a/plugins/kimchi/docs/API.md b/plugins/kimchi/docs/API.md new file mode 100644 index 000000000..fca41bcb0 --- /dev/null +++ b/plugins/kimchi/docs/API.md @@ -0,0 +1,1153 @@ +## 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. + * ips: A list of IP addresses associated with this MAC. + * 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. + * isvalid: True if is a valid 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 + + +### Collection: Tasks + +**URI:** /plugins/kimchi/tasks + +**Methods:** + +* **GET**: Retrieve a summarized list of current Tasks + +### Resource: Task + +**URI:** /plugins/kimchi/tasks/*:id* + +A task represents an asynchronous operation that is being performed by the +server. + +**Methods:** + +* **GET**: Retrieve the full description of the Task + * id: The Task ID is used to identify this Task in the API. + * status: The current status of the Task + * running: The task is running + * finished: The task has finished successfully + * failed: The task failed + * message: Human-readable details about the Task status + * target_uri: Resource URI related to the Task +* **POST**: *See Task Actions* + +**Actions (POST):** + +*No actions defined* + +### 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. + * _available_only: Filter to list only the host devices that are not + attached to a VM. + +### 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. + * display_repo_name: The same name retrieve from repo_name with any + possible variable expanded. + * 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 new file mode 100644 index 000000000..679aa182d --- /dev/null +++ b/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/docs/README-federation.md b/plugins/kimchi/docs/README-federation.md similarity index 70% rename from docs/README-federation.md rename to plugins/kimchi/docs/README-federation.md index b71a172e6..c184f4f7d 100644 --- a/docs/README-federation.md +++ b/plugins/kimchi/docs/README-federation.md @@ -1,11 +1,11 @@ Kimchi Project - Federation Feature =================================== -Federation feature is a mechanism to discover Kimchi peers in the same network. -It uses openSLP tool (http://www.openslp.org/) to register and find the Kimchi +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 Kimchi as it is not critical for KVM +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: @@ -43,18 +43,18 @@ To enable it, do the following: For system using iptables, do: sudo iptables -A INPUT -s -j ACCEPT -4. Start slpd service and make sure it is up while running Kimchi +4. Start slpd service and make sure it is up while running Wok sudo service slpd start -5. Enable federation on Kimchi by editing the /etc/kimchi/kimchi.conf file: +5. Enable federation on Wok by editing the /etc/wok/wok.conf file: federation = on -6. Then start Kimchi service - sudo service kimchid start +6. Then start Wok service + sudo service wokd start -The Kimchi server will be registered on openSLP on server starting up and will -be found by other Kimchi peers (with federation feature enabled) in the same +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 new file mode 100644 index 000000000..eeb64d988 --- /dev/null +++ b/plugins/kimchi/docs/README.md @@ -0,0 +1,246 @@ +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 python-magic + + # 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_packages.3F) +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 python-magic + + 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 python-magic + + 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, [this FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewalk/) +for python-ethtool, and [this FAQ](http://download.opensuse.org/repositories/home:/Simmphonie:/python/) for python-magic 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=, anonuid=,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@ovirt.org. diff --git a/docs/kimchi-guest.png b/plugins/kimchi/docs/kimchi-guest.png similarity index 100% rename from docs/kimchi-guest.png rename to plugins/kimchi/docs/kimchi-guest.png diff --git a/docs/kimchi-login.png b/plugins/kimchi/docs/kimchi-login.png similarity index 100% rename from docs/kimchi-login.png rename to plugins/kimchi/docs/kimchi-login.png diff --git a/docs/kimchi-templates.png b/plugins/kimchi/docs/kimchi-templates.png similarity index 100% rename from docs/kimchi-templates.png rename to plugins/kimchi/docs/kimchi-templates.png diff --git a/src/kimchi/i18n.py b/plugins/kimchi/i18n.py similarity index 95% rename from src/kimchi/i18n.py rename to plugins/kimchi/i18n.py index 1004aa415..07bebd450 100644 --- a/src/kimchi/i18n.py +++ b/plugins/kimchi/i18n.py @@ -24,23 +24,10 @@ messages = { "KCHAPI0001E": _("Unknown parameter %(value)s"), - "KCHAPI0002E": _("Delete is not allowed for %(resource)s"), - "KCHAPI0003E": _("%(resource)s does not implement update method"), - "KCHAPI0005E": _("Create is not allowed for %(resource)s"), - "KCHAPI0006E": _("Unable to parse JSON request"), - "KCHAPI0007E": _("This API only supports JSON"), - "KCHAPI0008E": _("Parameters does not match requirement in schema: %(err)s"), - "KCHAPI0009E": _("You don't have permission to perform this operation."), - - "KCHASYNC0001E": _("Datastore is not initiated in the model object."), - "KCHASYNC0002E": _("Unable to start task due error: %(err)s"), + "KCHASYNC0003E": _("Timeout of %(seconds)s seconds expired while running task '%(task)s."), - "KCHAUTH0001E": _("Authentication failed for user '%(username)s'. [Error code: %(code)s]"), - "KCHAUTH0002E": _("You are not authorized to access Kimchi"), - "KCHAUTH0003E": _("Specify %(item)s to login into Kimchi"), "KCHAUTH0004E": _("User %(user_id)s not found with given LDAP settings."), - "KCHAUTH0005E": _("Invalid LDAP configuration: %(item)s : %(value)s"), "KCHDEVS0001E": _('Unknown "_cap" specified'), "KCHDEVS0002E": _('"_passthrough" should be "true" or "false"'), @@ -286,13 +273,8 @@ "KCHPKGUPD0003E": _("Error while getting packages marked to be updated. Details: %(err)s"), "KCHPKGUPD0004E": _("There is no compatible package manager for this system."), - "KCHOBJST0001E": _("Unable to find %(item)s in datastore"), - "KCHUTILS0001E": _("Invalid URI %(uri)s"), - "KCHUTILS0002E": _("Timeout while running command '%(cmd)s' after %(seconds)s seconds"), "KCHUTILS0003E": _("Unable to choose a virtual machine name"), - "KCHUTILS0004E": _("Invalid data value '%(value)s'"), - "KCHUTILS0005E": _("Invalid data unit '%(unit)s'"), "KCHVMSTOR0002E": _("Invalid storage type. Types supported: 'cdrom', 'disk'"), "KCHVMSTOR0003E": _("The path '%(value)s' is not a valid local/remote path for the device"), diff --git a/src/kimchi/imageinfo.py b/plugins/kimchi/imageinfo.py similarity index 90% rename from src/kimchi/imageinfo.py rename to plugins/kimchi/imageinfo.py index 89d1e0a16..8a224955b 100644 --- a/src/kimchi/imageinfo.py +++ b/plugins/kimchi/imageinfo.py @@ -17,13 +17,13 @@ # 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 -import guestfs -from kimchi.exception import ImageFormatError, InvalidParameter, TimeoutExpired -from kimchi.utils import run_command, kimchi_log +from wok.exception import ImageFormatError, InvalidParameter, TimeoutExpired +from wok.utils import run_command, wok_log def probe_img_info(path): @@ -32,7 +32,7 @@ def probe_img_info(path): try: out = run_command(cmd, 10)[0] except TimeoutExpired: - kimchi_log.warning("Cannot decide format of base img %s", path) + wok_log.warning("Cannot decide format of base img %s", path) return None info = json.loads(out) diff --git a/src/kimchi/iscsi.py b/plugins/kimchi/iscsi.py similarity index 98% rename from src/kimchi/iscsi.py rename to plugins/kimchi/iscsi.py index b3e1b7858..02886ace2 100644 --- a/src/kimchi/iscsi.py +++ b/plugins/kimchi/iscsi.py @@ -20,7 +20,7 @@ import subprocess -from kimchi.exception import OperationFailed +from wok.exception import OperationFailed class TargetClient(object): diff --git a/src/kimchi/isoinfo.py b/plugins/kimchi/isoinfo.py similarity index 99% rename from src/kimchi/isoinfo.py rename to plugins/kimchi/isoinfo.py index 58dddcd0a..bc8d8a4f2 100644 --- a/src/kimchi/isoinfo.py +++ b/plugins/kimchi/isoinfo.py @@ -19,8 +19,8 @@ import contextlib import glob -import platform import os +import platform import re import stat import struct @@ -28,8 +28,8 @@ import urllib2 -from kimchi.exception import IsoFormatError -from kimchi.utils import check_url_path, kimchi_log +from wok.exception import IsoFormatError +from wok.utils import check_url_path, wok_log iso_dir = [ @@ -178,7 +178,7 @@ def probe(self): return (distro, version) msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s" - kimchi_log.debug(msg, self.path, self.volume_id) + wok_log.debug(msg, self.path, self.volume_id) return ('unknown', 'unknown') diff --git a/plugins/kimchi/kimchi.conf b/plugins/kimchi/kimchi.conf new file mode 100644 index 000000000..1bf78e4ac --- /dev/null +++ b/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/kimchi/kvmusertests.py b/plugins/kimchi/kvmusertests.py similarity index 97% rename from src/kimchi/kvmusertests.py rename to plugins/kimchi/kvmusertests.py index 5724267ea..35350d8e8 100644 --- a/src/kimchi/kvmusertests.py +++ b/plugins/kimchi/kvmusertests.py @@ -16,13 +16,13 @@ # 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 -import libvirt -from kimchi.rollbackcontext import RollbackContext +from wok.rollbackcontext import RollbackContext KVMUSERTEST_VM_NAME = "KVMUSERTEST_VM" diff --git a/plugins/kimchi/m4/ac_python_module.m4 b/plugins/kimchi/m4/ac_python_module.m4 new file mode 100644 index 000000000..32b9d7276 --- /dev/null +++ b/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 . +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 new file mode 100644 index 000000000..f84e6a5d7 --- /dev/null +++ b/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 , 1995-2000. +dnl Bruno Haible , 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 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 +$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 +$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 +$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 new file mode 100644 index 000000000..e2041b9b4 --- /dev/null +++ b/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 +#include ], + [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 +#include ], + [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 +#include +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 +#include +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 new file mode 100644 index 000000000..dd9102596 --- /dev/null +++ b/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 ], + [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 ], [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 new file mode 100644 index 000000000..ebb30528b --- /dev/null +++ b/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 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 new file mode 100644 index 000000000..c73bd8e3a --- /dev/null +++ b/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/plugins/kimchi/m4/lib-prefix.m4 b/plugins/kimchi/m4/lib-prefix.m4 new file mode 100644 index 000000000..1601ceaef --- /dev/null +++ b/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 . + 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 new file mode 100644 index 000000000..003704c4b --- /dev/null +++ b/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 , 1995-2000. +dnl Bruno Haible , 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 new file mode 100644 index 000000000..8bc921d4b --- /dev/null +++ b/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 , 1995-2000. +dnl Bruno Haible , 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 < "$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" < /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" <> "$ac_file.tmp" <, 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/kimchi/mockmodel.py b/plugins/kimchi/mockmodel.py similarity index 93% rename from src/kimchi/mockmodel.py rename to plugins/kimchi/mockmodel.py index 2f1f79b9a..0832b2089 100644 --- a/src/kimchi/mockmodel.py +++ b/plugins/kimchi/mockmodel.py @@ -22,37 +22,38 @@ import os import random import time - -import kimchi.model.cpuinfo -import kimchi.model.vmifaces - from lxml import objectify from lxml.builder import E -from kimchi import config -from kimchi import imageinfo -from kimchi import osinfo -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.model.debugreports import DebugReportsModel -from kimchi.model.host import DeviceModel -from kimchi.model.libvirtstoragepool import IscsiPoolDef, NetfsPoolDef -from kimchi.model.libvirtstoragepool import StoragePoolDef -from kimchi.model.model import Model -from kimchi.model.storagepools import StoragePoolModel -from kimchi.model.storagevolumes import StorageVolumeModel, StorageVolumesModel -from kimchi.model import storagevolumes -from kimchi.model.templates import LibvirtVMTemplate -from kimchi.model.users import PAMUsersModel -from kimchi.model.groups import PAMGroupsModel -from kimchi.objectstore import ObjectStore -from kimchi.utils import add_task, get_next_clone_name, kimchi_log -from kimchi.vmtemplate import VMTemplate -from kimchi.xmlutils.utils import xml_item_update +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 import vmifaces +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 import storagevolumes +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': '/storagepools/default-pool', - 'domain': 'test', 'arch': 'i686'} +mockmodel_defaults = { + 'storagepool': '/plugins/kimchi/storagepools/default-pool', + 'domain': 'test', 'arch': 'i686' +} storagevolumes.VALID_RAW_CONTENT = ['dos/mbr boot sector', 'x86 boot sector', 'data', 'empty'] @@ -79,9 +80,8 @@ def __init__(self, objstore_loc=None): self._mock_swupdate = MockSoftwareUpdate() self._mock_repositories = MockRepositories() - kimchi.model.cpuinfo.get_topo_capabilities = \ - MockModel.get_topo_capabilities - kimchi.model.vmifaces.getDHCPLeases = MockModel.getDHCPLeases + cpuinfo.get_topo_capabilities = MockModel.get_topo_capabilities + vmifaces.getDHCPLeases = MockModel.getDHCPLeases libvirt.virConnect.defineXML = MockModel.domainDefineXML libvirt.virDomain.XMLDesc = MockModel.domainXMLDesc libvirt.virDomain.undefine = MockModel.undefineDomain @@ -259,8 +259,8 @@ def _get_volume_path(self, pool, vol): return MockModel._libvirt_get_vol_path(pool, vol) def _gen_debugreport_file(self, name): - return add_task('/debugreports/%s' % name, self._create_log, - self.objstore, 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() @@ -289,10 +289,10 @@ def _update_lvm_disks(self, pool_name, disks): conn.storagePoolDefineXML(ET.tostring(root), 0) def _mock_host_shutdown(self, *name): - kimchi_log.info("The host system will be shutted down") + wok_log.info("The host system will be shutted down") def _mock_host_reboot(self, *name): - kimchi_log.info("The host system will be rebooted") + wok_log.info("The host system will be rebooted") def _mock_storagevolumes_create(self, pool, params): vol_source = ['url', 'capacity'] @@ -369,8 +369,8 @@ 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('/host/swupdate', self._mock_swupdate.doUpdate, - self.objstore) + 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): @@ -421,8 +421,9 @@ def _mock_vm_clone(self, 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'/vms/%s/snapshots/%s' % (vm_name, name), - self._vmsnapshots_create_task, self.objstore, params) + 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): diff --git a/plugins/kimchi/model/Makefile.am b/plugins/kimchi/model/Makefile.am new file mode 100644 index 000000000..f4f4750e5 --- /dev/null +++ b/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/kimchi/model/__init__.py b/plugins/kimchi/model/__init__.py similarity index 100% rename from src/kimchi/model/__init__.py rename to plugins/kimchi/model/__init__.py diff --git a/src/kimchi/model/config.py b/plugins/kimchi/model/config.py similarity index 86% rename from src/kimchi/model/config.py rename to plugins/kimchi/model/config.py index fe2a5291a..b6cc4d919 100644 --- a/src/kimchi/model/config.py +++ b/plugins/kimchi/model/config.py @@ -17,22 +17,23 @@ # 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 -import cherrypy +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 kimchi.basemodel import Singleton -from kimchi.config import config as kconfig -from kimchi.config import find_qemu_binary, get_version -from kimchi.distroloader import DistroLoader -from kimchi.exception import NotFoundError -from kimchi.model.debugreports import DebugReportsModel -from kimchi.model.featuretests import FeatureTests, FEATURETEST_POOL_NAME -from kimchi.model.featuretests import FEATURETEST_VM_NAME -from kimchi.repositories import Repositories -from kimchi.screenshot import VMScreenshot -from kimchi.swupdate import SoftwareUpdate -from kimchi.utils import check_url_path, kimchi_log, run_command +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): @@ -84,7 +85,7 @@ def _clean_leftovers(self): FeatureTests.enable_libvirt_error_logging() def _set_capabilities(self): - kimchi_log.info("*** Running feature tests ***") + 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) @@ -97,15 +98,15 @@ def _set_capabilities(self): if FeatureTests.libvirt_supports_iso_stream(conn, p): self.libvirt_stream_protocols.append(p) - kimchi_log.info("*** Feature tests completed ***") + 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: - kimchi_log.error('Failed to find qemu binary dependencies: %s', - err) + 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'): diff --git a/src/kimchi/model/cpuinfo.py b/plugins/kimchi/model/cpuinfo.py similarity index 94% rename from src/kimchi/model/cpuinfo.py rename to plugins/kimchi/model/cpuinfo.py index 548aa3e75..299e445c6 100644 --- a/src/kimchi/model/cpuinfo.py +++ b/plugins/kimchi/model/cpuinfo.py @@ -18,11 +18,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import platform - from xml.etree import ElementTree as ET -from kimchi.exception import InvalidParameter, InvalidOperation -from kimchi.utils import kimchi_log, run_command +from wok.exception import InvalidParameter, InvalidOperation +from wok.utils import run_command, wok_log + ARCH = 'power' if platform.machine().startswith('ppc') else 'x86' @@ -59,11 +59,11 @@ def __init__(self, **kargs): connect = self.conn.get() libvirt_topology = get_topo_capabilities(connect) except Exception as e: - kimchi_log.info("Unable to get CPU topology capabilities: %s" - % e.message) + wok_log.info("Unable to get CPU topology capabilities: %s" + % e.message) return if libvirt_topology is None: - kimchi_log.info("cpu_info topology not supported.") + wok_log.info("cpu_info topology not supported.") return if ARCH == 'power': diff --git a/src/kimchi/model/debugreports.py b/plugins/kimchi/model/debugreports.py similarity index 88% rename from src/kimchi/model/debugreports.py rename to plugins/kimchi/model/debugreports.py index 5f74da837..bee10b6af 100644 --- a/src/kimchi/model/debugreports.py +++ b/plugins/kimchi/model/debugreports.py @@ -25,12 +25,13 @@ import subprocess import time -from kimchi import config -from kimchi.exception import InvalidParameter, KimchiException, NotFoundError -from kimchi.exception import OperationFailed -from kimchi.model.tasks import TaskModel -from kimchi.utils import add_task, kimchi_log -from kimchi.utils import run_command +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 .. import config +from tasks import TaskModel class DebugReportsModel(object): @@ -62,8 +63,8 @@ def _gen_debugreport_file(self, name): gen_cmd = self.get_system_report_tool() if gen_cmd is not None: - return add_task('/debugreports/%s' % name, gen_cmd, self.objstore, - name) + return add_task('/plugins/kimchi/debugreports/%s' % name, gen_cmd, + self.objstore, name) raise OperationFailed("KCHDR0002E") @@ -95,8 +96,8 @@ def log_error(e): break # Some error in sosreport happened if reportFile is None: - kimchi_log.error('Debug report file not found. See sosreport ' - 'output for detail:\n%s', output) + 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}) @@ -107,19 +108,19 @@ def log_error(e): # Moving report msg = 'Moving debug report file "%s" to "%s"' % (reportFile, target) - kimchi_log.info(msg) + wok_log.info(msg) shutil.move(reportFile, target) # Deleting md5 msg = 'Deleting report md5 file: "%s"' % (md5_report_file) - kimchi_log.info(msg) + wok_log.info(msg) with open(md5_report_file) as f: md5 = f.read().strip() - kimchi_log.info('Md5 file content: "%s"', md5) + wok_log.info('Md5 file content: "%s"', md5) os.remove(md5_report_file) cb('OK', True) return - except KimchiException as e: + except WokException as e: log_error(e) raise @@ -151,7 +152,7 @@ def get_system_report_tool(): if retcode == 0: return helper_tool['fn'] except Exception, e: - kimchi_log.info('Exception running command: %s', e) + wok_log.info('Exception running command: %s', e) return None @@ -172,7 +173,8 @@ def lookup(self, 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("/data/debugreports", file_target) + file_target = os.path.join("plugins/kimchi/data/debugreports", + file_target) return {'uri': file_target, 'ctime': ctime} @@ -189,7 +191,7 @@ def update(self, name, params): raise InvalidParameter('KCHDR0008E', {'name': params['name']}) shutil.move(file_source, file_target) - kimchi_log.info('%s renamed to %s' % (file_source, file_target)) + wok_log.info('%s renamed to %s' % (file_source, file_target)) return params['name'] def delete(self, name): diff --git a/src/kimchi/model/diskutils.py b/plugins/kimchi/model/diskutils.py similarity index 85% rename from src/kimchi/model/diskutils.py rename to plugins/kimchi/model/diskutils.py index 0be2024b8..350e6eb55 100644 --- a/src/kimchi/model/diskutils.py +++ b/plugins/kimchi/model/diskutils.py @@ -17,11 +17,11 @@ # 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 kimchi.exception import OperationFailed, NotFoundError -from kimchi.model.vms import VMModel, VMsModel -from kimchi.utils import kimchi_log -from kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks +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, @@ -35,7 +35,7 @@ def get_disk_used_by(objstore, conn, path): try: used_by = session.get('storagevolume', path)['used_by'] except (KeyError, NotFoundError): - kimchi_log.info('Volume %s not found in obj store.' % path) + 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) @@ -54,9 +54,9 @@ def get_disk_used_by(objstore, conn, path): # used_by to be out of sync, data corruption could # occour if a disk is added to two guests # unknowingly. - kimchi_log.error('Unable to store storage volume id in' - ' objectstore due error: %s', - e.message) + 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: diff --git a/src/kimchi/model/featuretests.py b/plugins/kimchi/model/featuretests.py similarity index 96% rename from src/kimchi/model/featuretests.py rename to plugins/kimchi/model/featuretests.py index 4075d7cb8..7c4e9ce20 100644 --- a/src/kimchi/model/featuretests.py +++ b/plugins/kimchi/model/featuretests.py @@ -22,11 +22,11 @@ import lxml.etree as ET import platform import subprocess - from lxml.builder import E -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import kimchi_log, run_command, servermethod +from wok.rollbackcontext import RollbackContext +from wok.utils import run_command, servermethod, wok_log + FEATURETEST_VM_NAME = "FEATURETEST_VM" FEATURETEST_POOL_NAME = "FEATURETEST_POOL" @@ -132,7 +132,7 @@ def libvirt_supports_iso_stream(conn, protocol): dom.undefine() return True except libvirt.libvirtError, e: - kimchi_log.error(e.message) + wok_log.error(e.message) return False finally: FeatureTests.enable_libvirt_error_logging() @@ -147,7 +147,7 @@ def _get_xml(): FeatureTests.disable_libvirt_error_logging() conn.findStoragePoolSources('netfs', _get_xml(), 0) except libvirt.libvirtError as e: - kimchi_log.error(e.message) + wok_log.error(e.message) if e.get_error_code() == 38: # if libvirt cannot find showmount, # it returns 38--general system call failure @@ -189,7 +189,7 @@ def libvirt_support_fc_host(conn): def kernel_support_vfio(): out, err, rc = run_command(['modprobe', 'vfio-pci']) if rc != 0: - kimchi_log.warning("Unable to load Kernal module vfio-pci.") + wok_log.warning("Unable to load Kernal module vfio-pci.") return False return True diff --git a/src/kimchi/model/groups.py b/plugins/kimchi/model/groups.py similarity index 98% rename from src/kimchi/model/groups.py rename to plugins/kimchi/model/groups.py index 0af3f8f32..fc63d68d7 100644 --- a/src/kimchi/model/groups.py +++ b/plugins/kimchi/model/groups.py @@ -19,7 +19,7 @@ import grp -from kimchi.config import config +from wok.config import config class GroupsModel(object): diff --git a/src/kimchi/model/host.py b/plugins/kimchi/model/host.py similarity index 96% rename from src/kimchi/model/host.py rename to plugins/kimchi/model/host.py index 1325fdc3f..e4c03915c 100644 --- a/src/kimchi/model/host.py +++ b/plugins/kimchi/model/host.py @@ -19,27 +19,27 @@ import libvirt import os -import time import platform +import psutil +import time +from cherrypy.process.plugins import BackgroundTask from collections import defaultdict from lxml import objectify -import psutil -from cherrypy.process.plugins import BackgroundTask +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 kimchi import disks -from kimchi import netinfo -from kimchi.basemodel import Singleton -from kimchi.model import hostdev -from kimchi.exception import InvalidOperation, InvalidParameter -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.model.config import CapabilitiesModel -from kimchi.model.tasks import TaskModel -from kimchi.model.vms import DOM_STATE_MAP, VMModel, VMsModel -from kimchi.repositories import Repositories -from kimchi.swupdate import SoftwareUpdate -from kimchi.utils import add_task, kimchi_log -from kimchi.xmlutils.utils import xpath_get_text +import hostdev +from .. import disks +from .. import netinfo +from ..repositories import Repositories +from ..swupdate import SoftwareUpdate +from config import CapabilitiesModel +from tasks import TaskModel +from vms import DOM_STATE_MAP, VMModel, VMsModel HOST_STATS_INTERVAL = 1 @@ -138,9 +138,9 @@ def swupdate(self, *name): if pkgs == 0: raise OperationFailed('KCHPKGUPD0001E') - kimchi_log.debug('Host is going to be updated.') - taskid = add_task('/host/swupdate', swupdate.doUpdate, self.objstore, - None) + 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): @@ -149,7 +149,7 @@ def shutdown(self, args=None): if len(running_vms) > 0: raise OperationFailed("KCHHOST0001E") - kimchi_log.info('Host is going to shutdown.') + wok_log.info('Host is going to shutdown.') os.system('shutdown -h now') def reboot(self, args=None): @@ -158,7 +158,7 @@ def reboot(self, args=None): if len(running_vms) > 0: raise OperationFailed("KCHHOST0002E") - kimchi_log.info('Host is going to reboot.') + wok_log.info('Host is going to reboot.') os.system('reboot') def _get_vms_list_by_state(self, state): diff --git a/src/kimchi/model/hostdev.py b/plugins/kimchi/model/hostdev.py similarity index 95% rename from src/kimchi/model/hostdev.py rename to plugins/kimchi/model/hostdev.py index 07c1a4a38..46d7e1368 100644 --- a/src/kimchi/model/hostdev.py +++ b/plugins/kimchi/model/hostdev.py @@ -21,9 +21,10 @@ from pprint import pformat from pprint import pprint -from kimchi.model.libvirtconnection import LibvirtConnection -from kimchi.utils import kimchi_log -from kimchi.xmlutils.utils import dictize +from wok.utils import wok_log +from wok.xmlutils.utils import dictize + +from libvirtconnection import LibvirtConnection def _get_all_host_dev_infos(libvirt_conn): @@ -42,8 +43,8 @@ def _get_dev_info_tree(dev_infos): try: parent = devs[dev_info['parent']] except KeyError: - kimchi_log.error('Parent %s of device %s does not exist.', - dev_info['parent'], dev_info['name']) + wok_log.error('Parent %s of device %s does not exist.', + dev_info['parent'], dev_info['name']) continue try: @@ -97,8 +98,8 @@ def get_iommu_group(dev_info): try: parent_info = dev_dict[parent] except KeyError: - kimchi_log.error("Parent %s of device %s does not exist", - parent, dev_info['name']) + wok_log.error("Parent %s of device %s does not exist", + parent, dev_info['name']) break try: @@ -185,7 +186,7 @@ def get_dev_info(node_dev): if dev_type in ('net', 'pci', 'scsi_host', 'storage', 'usb_device'): return globals()['_get_%s_dev_info' % dev_type](info) - kimchi_log.error("Unknown device type: %s", dev_type) + wok_log.error("Unknown device type: %s", dev_type) return info diff --git a/src/kimchi/model/interfaces.py b/plugins/kimchi/model/interfaces.py similarity index 91% rename from src/kimchi/model/interfaces.py rename to plugins/kimchi/model/interfaces.py index 4069caf54..149afe3a5 100644 --- a/src/kimchi/model/interfaces.py +++ b/plugins/kimchi/model/interfaces.py @@ -17,9 +17,10 @@ # 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 kimchi import netinfo -from kimchi.exception import NotFoundError -from kimchi.model.networks import NetworksModel +from wok.exception import NotFoundError + +from .. import netinfo +from networks import NetworksModel class InterfacesModel(object): diff --git a/src/kimchi/model/libvirtconnection.py b/plugins/kimchi/model/libvirtconnection.py similarity index 87% rename from src/kimchi/model/libvirtconnection.py rename to plugins/kimchi/model/libvirtconnection.py index 7a5337c16..73f3dcf44 100644 --- a/src/kimchi/model/libvirtconnection.py +++ b/plugins/kimchi/model/libvirtconnection.py @@ -17,13 +17,12 @@ # 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 threading -import time - import cherrypy import libvirt +import threading +import time -from kimchi.utils import kimchi_log +from wok.utils import wok_log class LibvirtConnection(object): @@ -75,9 +74,9 @@ def wrapper(*args, **kwargs): libvirt.VIR_ERR_NO_CONNECT, libvirt.VIR_ERR_INVALID_CONN) if edom in EDOMAINS and ecode in ECODES: - kimchi_log.error('Connection to libvirt broken. ' - 'Recycling. ecode: %d edom: %d' % - (ecode, edom)) + wok_log.error('Connection to libvirt broken. ' + 'Recycling. ecode: %d edom: %d' % + (ecode, edom)) with LibvirtConnection._connectionLock: self._connections[conn_id] = None raise @@ -95,13 +94,13 @@ def wrapper(*args, **kwargs): conn = libvirt.open(self.uri) break except libvirt.libvirtError: - kimchi_log.error('Unable to connect to libvirt.') + wok_log.error('Unable to connect to libvirt.') if not retries: - kimchi_log.error("Unable to establish connection " - "with libvirt. Please check " - "your libvirt URI which is often " - "defined in " - "/etc/libvirt/libvirt.conf") + 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) diff --git a/src/kimchi/model/libvirtstoragepool.py b/plugins/kimchi/model/libvirtstoragepool.py similarity index 97% rename from src/kimchi/model/libvirtstoragepool.py rename to plugins/kimchi/model/libvirtstoragepool.py index c6deafca6..b22856bd0 100644 --- a/src/kimchi/model/libvirtstoragepool.py +++ b/plugins/kimchi/model/libvirtstoragepool.py @@ -17,17 +17,17 @@ # 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 -import lxml.etree as ET from lxml.builder import E -import libvirt +from wok.exception import InvalidParameter, OperationFailed, TimeoutExpired +from wok.rollbackcontext import RollbackContext +from wok.utils import parse_cmd_output, run_command, wok_log -from kimchi.exception import InvalidParameter, OperationFailed, TimeoutExpired -from kimchi.iscsi import TargetClient -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import kimchi_log, parse_cmd_output, run_command +from ..iscsi import TargetClient class StoragePoolDef(object): @@ -165,7 +165,7 @@ def prepare(self, conn=None): 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 - kimchi_log.info(msg) + wok_log.info(msg) # Path for Fibre Channel scsi hosts self.poolArgs['path'] = '/dev/disk/by-path' if not self.poolArgs['source']['adapter']['type']: diff --git a/src/kimchi/model/model.py b/plugins/kimchi/model/model.py similarity index 86% rename from src/kimchi/model/model.py rename to plugins/kimchi/model/model.py index 40ebc98bb..0c94f6341 100644 --- a/src/kimchi/model/model.py +++ b/plugins/kimchi/model/model.py @@ -20,10 +20,11 @@ import inspect import os -from kimchi.basemodel import BaseModel -from kimchi.model.libvirtconnection import LibvirtConnection -from kimchi.objectstore import ObjectStore -from kimchi.utils import import_module, listPathModules +from wok.basemodel import BaseModel +from wok.objectstore import ObjectStore +from wok.utils import import_module, listPathModules + +from libvirtconnection import LibvirtConnection class Model(BaseModel): @@ -41,7 +42,7 @@ def __init__(self, libvirt_uri=None, objstore_loc=None): if mod_name.startswith("_") or mod_name == this_mod: continue - module = import_module('model.' + mod_name) + 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: diff --git a/src/kimchi/model/networks.py b/plugins/kimchi/model/networks.py similarity index 93% rename from src/kimchi/model/networks.py rename to plugins/kimchi/model/networks.py index 275e12b78..b57986597 100644 --- a/src/kimchi/model/networks.py +++ b/plugins/kimchi/model/networks.py @@ -17,25 +17,24 @@ # 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 sys -import time - import ipaddr import libvirt - +import sys +import time from xml.sax.saxutils import escape -from kimchi import netinfo -from kimchi import network as knetwork -from kimchi.config import paths -from kimchi.exception import InvalidOperation, InvalidParameter -from kimchi.exception import MissingParameter, NotFoundError, OperationFailed -from kimchi.osinfo import defaults as tmpl_defaults -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import kimchi_log, run_command -from kimchi.xmlutils.network import create_vlan_tagged_bridge_xml -from kimchi.xmlutils.network import to_network_xml -from kimchi.xmlutils.utils import xpath_get_text +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' @@ -52,16 +51,17 @@ def _check_default_networks(self): conn = self.conn.get() error_msg = ("Please, check the configuration in %s/template.conf to " - "ensure it lists only valid networks." % paths.conf_dir) + "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." - kimchi_log.error(msg, net_name) - kimchi_log.error(error_msg) - kimchi_log.error("Details: %s", e.message) + 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: @@ -69,9 +69,9 @@ def _check_default_networks(self): net.create() except libvirt.libvirtError as e: msg = "Fatal: Unable to activate network %s." - kimchi_log.error(msg, net_name) - kimchi_log.error(error_msg) - kimchi_log.error("Details: %s", e.message) + 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): @@ -211,7 +211,7 @@ def _create_vlan_tagged_bridge(self, interface, vlan_id): try: bridges.append(net.bridgeName()) except libvirt.libvirtError, e: - kimchi_log.error(e.message) + wok_log.error(e.message) if br_name in bridges: raise InvalidOperation("KCHNET0010E", {'iface': br_name}) diff --git a/src/kimchi/model/peers.py b/plugins/kimchi/model/peers.py similarity index 78% rename from src/kimchi/model/peers.py rename to plugins/kimchi/model/peers.py index 0d4227ba3..757736402 100644 --- a/src/kimchi/model/peers.py +++ b/plugins/kimchi/model/peers.py @@ -21,8 +21,8 @@ import re import socket -from kimchi.config import config -from kimchi.utils import kimchi_log, run_command +from wok.config import config +from wok.utils import run_command, wok_log class PeersModel(object): @@ -37,34 +37,34 @@ def __init__(self, **kargs): self.url = hostname + ":" + port cmd = ["slptool", "register", - "service:kimchid://%s" % self.url] + "service:wokd://%s" % self.url] out, error, ret = run_command(cmd) if out and len(out) != 0: - kimchi_log.error("Unable to register server on openSLP." - " Details: %s" % out) + 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:kimchid://%s" % self.url] + "service:wokd://%s" % self.url] out, error, ret = run_command(cmd) if out and len(out) != 0: - kimchi_log.error("Unable to deregister server on openSLP." - " Details: %s" % out) + 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:kimchid"] + 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:kimchid://(.*?),.*", server) + match = re.match("service:wokd://(.*?),.*", server) peer = match.group(1) if peer != self.url: peers.append("https://" + peer) diff --git a/src/kimchi/model/storagepools.py b/plugins/kimchi/model/storagepools.py similarity index 89% rename from src/kimchi/model/storagepools.py rename to plugins/kimchi/model/storagepools.py index aa075cd76..0db2ef436 100644 --- a/src/kimchi/model/storagepools.py +++ b/plugins/kimchi/model/storagepools.py @@ -20,19 +20,20 @@ import libvirt import lxml.etree as ET import sys - from lxml.builder import E -from kimchi.config import config, paths -from kimchi.scan import Scanner -from kimchi.exception import InvalidOperation, MissingParameter -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.model.config import CapabilitiesModel -from kimchi.model.host import DeviceModel -from kimchi.model.libvirtstoragepool import StoragePoolDef -from kimchi.osinfo import defaults as tmpl_defaults -from kimchi.utils import add_task, kimchi_log, pool_name_from_uri, run_command -from kimchi.xmlutils.utils import xpath_get_text +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' @@ -71,7 +72,7 @@ def _check_default_pools(self): pools = {} default_pool = tmpl_defaults['storagepool'] - default_pool = default_pool.split('/')[2] + default_pool = default_pool.split('/')[-1] pools[default_pool] = {} if default_pool == 'default': @@ -81,7 +82,8 @@ def _check_default_pools(self): 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." % paths.conf_dir) + "ensure it has a valid storage pool." % + PluginPaths('kimchi').conf_dir) conn = self.conn.get() for pool_name in pools: @@ -91,8 +93,8 @@ def _check_default_pools(self): pool_path = pools[pool_name].get('path') if pool_path is None: msg = "Fatal: Unable to find storage pool %s. " + error_msg - kimchi_log.error(msg % pool_name) - kimchi_log.error("Details: %s", e.message) + wok_log.error(msg % pool_name) + wok_log.error("Details: %s", e.message) sys.exit(1) # Try to create the pool @@ -104,8 +106,8 @@ def _check_default_pools(self): except libvirt.libvirtError, e: msg = "Fatal: Unable to create storage pool %s. " msg += error_msg - kimchi_log.error(msg % pool_name) - kimchi_log.error("Details: %s", e.message) + wok_log.error(msg % pool_name) + wok_log.error("Details: %s", e.message) sys.exit(1) # Build and set autostart value to pool @@ -125,8 +127,8 @@ def _check_default_pools(self): except libvirt.libvirtError, e: msg = "Fatal: Unable to craete storage pool %s. " msg += error_msg - kimchi_log.error(msg % pool_name) - kimchi_log.error("Details: %s", e.message) + wok_log.error(msg % pool_name) + wok_log.error("Details: %s", e.message) sys.exit(1) def get_list(self): @@ -191,7 +193,7 @@ def create(self, params): pool = conn.storagePoolDefineXML(xml, 0) except libvirt.libvirtError as e: - kimchi_log.error("Problem creating Storage Pool: %s", e) + wok_log.error("Problem creating Storage Pool: %s", e) raise OperationFailed("KCHPOOL0007E", {'name': name, 'err': e.get_error_message()}) @@ -211,9 +213,9 @@ def create(self, params): output, error, returncode = run_command(['setsebool', '-P', 'virt_use_nfs=1']) if error or returncode: - kimchi_log.error("Unable to set virt_use_nfs=1. If you use " - "SELinux, this may prevent NFS pools from " - "being used.") + 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): @@ -225,7 +227,7 @@ def _clean_scan(self, pool_name): session.delete('scanning', pool_name) except Exception, e: err = "Exception %s occured when cleaning scan result" - kimchi_log.debug(err % e.message) + wok_log.debug(err % e.message) def _do_deep_scan(self, params): scan_params = dict(ignore_list=[]) @@ -240,11 +242,11 @@ def _do_deep_scan(self, params): scan_params['ignore_list'].append(res['path']) except Exception, e: err = "Exception %s occured when get ignore path" - kimchi_log.debug(err % e.message) + 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('/storagepools/%s' % ISO_POOL_NAME, + 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: @@ -282,10 +284,10 @@ def _get_storagepool_vols_num(self, pool): # 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 - kimchi_log.error("ERROR: Storage Pool get vol count: %s " - % e.get_error_message()) - kimchi_log.error("ERROR: Storage Pool get vol count error no: %s " - % e.get_error_code()) + 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", @@ -337,9 +339,8 @@ def lookup(self, name): # 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): - kimchi_log.debug("NFS pool %s is offline, reason: NFS " - "server %s is unreachable.", name, - source['addr']) + 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 @@ -376,8 +377,8 @@ def _update_lvm_disks(self, pool_name, disks): lsblk_cmd = ['lsblk', disk] output, error, returncode = run_command(lsblk_cmd) if returncode != 0: - kimchi_log.error('%s is not a valid disk/partition. Could not ' - 'add it to the pool %s.', disk, pool_name) + 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 @@ -386,7 +387,7 @@ def _update_lvm_disks(self, pool_name, disks): output, error, returncode = run_command(vgextend_cmd) if returncode != 0: msg = "Could not add disks to pool %s, error: %s" - kimchi_log.error(msg, pool_name, error) + wok_log.error(msg, pool_name, error) raise OperationFailed('KCHPOOL0028E', {'pool': pool_name, 'err': error}) # refreshing pool state diff --git a/src/kimchi/model/storageservers.py b/plugins/kimchi/model/storageservers.py similarity index 95% rename from src/kimchi/model/storageservers.py rename to plugins/kimchi/model/storageservers.py index dcdb74a86..accc5f523 100644 --- a/src/kimchi/model/storageservers.py +++ b/plugins/kimchi/model/storageservers.py @@ -17,8 +17,9 @@ # 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 kimchi.exception import NotFoundError -from kimchi.model.storagepools import StoragePoolModel, StoragePoolsModel +from wok.exception import NotFoundError + +from storagepools import StoragePoolModel, StoragePoolsModel # Types of remote storage servers supported STORAGE_SERVERS = ['netfs', 'iscsi'] diff --git a/src/kimchi/model/storagetargets.py b/plugins/kimchi/model/storagetargets.py similarity index 93% rename from src/kimchi/model/storagetargets.py rename to plugins/kimchi/model/storagetargets.py index 159f98716..4090b4545 100644 --- a/src/kimchi/model/storagetargets.py +++ b/plugins/kimchi/model/storagetargets.py @@ -22,9 +22,10 @@ from lxml import objectify from lxml.builder import E -from kimchi.model.config import CapabilitiesModel -from kimchi.model.storageservers import STORAGE_SERVERS -from kimchi.utils import kimchi_log, patch_find_nfs_target +from wok.utils import patch_find_nfs_target, wok_log + +from config import CapabilitiesModel +from storageservers import STORAGE_SERVERS class StorageTargetsModel(object): @@ -51,7 +52,7 @@ def get_list(self, storage_server, _target_type=None, _server_port=None): ret = conn.findStoragePoolSources(target_type, xml, 0) except libvirt.libvirtError as e: err = "Query storage pool source fails because of %s" - kimchi_log.warning(err, e.get_error_message()) + wok_log.warning(err, e.get_error_message()) continue targets = self._parse_target_source_result(target_type, ret) @@ -78,7 +79,7 @@ def get_list(self, storage_server, _target_type=None, _server_port=None): except libvirt.libvirtError as e: err = "Query storage pool source fails because of %s" - kimchi_log.warning(err, e.get_error_message()) + 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 diff --git a/src/kimchi/model/storagevolumes.py b/plugins/kimchi/model/storagevolumes.py similarity index 95% rename from src/kimchi/model/storagevolumes.py rename to plugins/kimchi/model/storagevolumes.py index 75cab9c6e..7ae053b9e 100644 --- a/src/kimchi/model/storagevolumes.py +++ b/plugins/kimchi/model/storagevolumes.py @@ -18,6 +18,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import contextlib +import libvirt import lxml.etree as ET import magic import os @@ -27,18 +28,17 @@ import urllib2 from lxml.builder import E -import libvirt +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 kimchi.config import READONLY_POOL_TYPE -from kimchi.exception import InvalidOperation, InvalidParameter, IsoFormatError -from kimchi.exception import MissingParameter, NotFoundError, OperationFailed -from kimchi.isoinfo import IsoImage -from kimchi.model.diskutils import get_disk_used_by, set_disk_used_by -from kimchi.model.storagepools import StoragePoolModel -from kimchi.model.tasks import TaskModel -from kimchi.utils import add_task, get_next_clone_name, get_unique_file_name -from kimchi.utils import kimchi_log -from kimchi.xmlutils.utils import xpath_get_text +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 +from tasks import TaskModel VOLUME_TYPE_MAP = {0: 'file', @@ -119,7 +119,8 @@ def create(self, pool_name, params): raise InvalidParameter('KCHVOL0001E', {'name': name}) params['pool'] = pool_name - targeturi = '/storagepools/%s/storagevolumes/%s' % (pool_name, 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) @@ -238,7 +239,7 @@ def _stream_handler(stream, nbytes, fd): if virt_vol: virt_vol.delete(0) except libvirt.libvirtError, virt_e: - kimchi_log.error(virt_e.message) + wok_log.error(virt_e.message) finally: raise OperationFailed('KCHVOL0007E', {'name': name, 'pool': pool_name, @@ -422,8 +423,8 @@ def clone(self, pool, name, new_pool=None, new_name=None): 'name': name, 'new_pool': new_pool, 'new_name': new_name} - taskid = add_task(u'/storagepools/%s/storagevolumes/%s' % - (pool, new_name), self._clone_task, self.objstore, + taskid = add_task(u'/plugins/kimchi/storagepools/%s/storagevolumes/%s' + % (pool, new_name), self._clone_task, self.objstore, params) return self.task.lookup(taskid) @@ -547,8 +548,8 @@ def get_list(self): volumes = pool.listVolumes() except Exception, e: # Skip inactive pools - kimchi_log.debug("Shallow scan: skipping pool %s because of " - "error: %s", (pool_name, e.message)) + wok_log.debug("Shallow scan: skipping pool %s because of " + "error: %s", (pool_name, e.message)) continue for volume in volumes: diff --git a/src/kimchi/model/tasks.py b/plugins/kimchi/model/tasks.py similarity index 97% rename from src/kimchi/model/tasks.py rename to plugins/kimchi/model/tasks.py index 61bc2f395..678fdc202 100644 --- a/src/kimchi/model/tasks.py +++ b/plugins/kimchi/model/tasks.py @@ -20,7 +20,7 @@ import time -from kimchi.exception import TimeoutExpired +from wok.exception import TimeoutExpired class TasksModel(object): diff --git a/src/kimchi/model/templates.py b/plugins/kimchi/model/templates.py similarity index 96% rename from src/kimchi/model/templates.py rename to plugins/kimchi/model/templates.py index ef83706f6..4f0b204d8 100644 --- a/src/kimchi/model/templates.py +++ b/plugins/kimchi/model/templates.py @@ -18,19 +18,19 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import copy +import libvirt import os import stat -import libvirt +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 kimchi.exception import InvalidOperation, InvalidParameter -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.kvmusertests import UserTests -from kimchi.model.cpuinfo import CPUInfoModel -from kimchi.utils import pool_name_from_uri -from kimchi.utils import probe_file_permission_as_user, run_setfacl_set_attr -from kimchi.vmtemplate import VMTemplate -from kimchi.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): @@ -76,7 +76,7 @@ def create(self, params): pool_name = pool_name_from_uri(pool_uri) pool = conn.storagePoolLookupByName(pool_name.encode("utf-8")) except Exception: - raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name, + raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri, 'template': name}) tmp_volumes = [disk['volume'] for disk in params.get('disks', []) @@ -194,7 +194,7 @@ def update(self, name, params): pool_name = pool_name_from_uri(pool_uri) pool = conn.storagePoolLookupByName(pool_name.encode("utf-8")) except Exception: - raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name, + raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri, 'template': name}) tmp_volumes = [disk['volume'] for disk in new_t.get('disks', []) if 'volume' in disk] @@ -239,7 +239,7 @@ def _storage_validate(self): conn = self.conn.get() pool = conn.storagePoolLookupByName(pool_name.encode("utf-8")) except libvirt.libvirtError: - raise InvalidParameter("KCHTMPL0004E", {'pool': pool_name, + raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri, 'template': self.name}) if not pool.isActive(): diff --git a/src/kimchi/model/users.py b/plugins/kimchi/model/users.py similarity index 97% rename from src/kimchi/model/users.py rename to plugins/kimchi/model/users.py index 1422baea9..2fa65dd81 100644 --- a/src/kimchi/model/users.py +++ b/plugins/kimchi/model/users.py @@ -20,8 +20,8 @@ import ldap import pwd -from kimchi.config import config -from kimchi.exception import NotFoundError +from wok.config import config +from wok.exception import NotFoundError class UsersModel(object): diff --git a/src/kimchi/model/utils.py b/plugins/kimchi/model/utils.py similarity index 98% rename from src/kimchi/model/utils.py rename to plugins/kimchi/model/utils.py index 5f47e6ad4..20bcb2632 100644 --- a/src/kimchi/model/utils.py +++ b/plugins/kimchi/model/utils.py @@ -23,7 +23,8 @@ from lxml import etree from lxml.builder import E -from kimchi.exception import OperationFailed +from wok.exception import OperationFailed + KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi" KIMCHI_NAMESPACE = "kimchi" diff --git a/src/kimchi/model/vmhostdevs.py b/plugins/kimchi/model/vmhostdevs.py similarity index 95% rename from src/kimchi/model/vmhostdevs.py rename to plugins/kimchi/model/vmhostdevs.py index a9f6d77c8..5baff2f16 100644 --- a/src/kimchi/model/vmhostdevs.py +++ b/plugins/kimchi/model/vmhostdevs.py @@ -18,21 +18,21 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import glob -import os - import libvirt +import os +import platform from lxml import etree, objectify from lxml.builder import E -from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError -from kimchi.exception import OperationFailed -from kimchi.model.config import CapabilitiesModel -from kimchi.model.host import DeviceModel, DevicesModel -from kimchi.model.utils import get_vm_config_flag -from kimchi.model.vms import DOM_STATE_MAP, VMModel -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import kimchi_log, run_command -import platform +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): @@ -108,7 +108,7 @@ def _validate_pci_passthrough_env(): out, err, rc = run_command(['setsebool', '-P', 'virt_use_sysfs=on']) if rc != 0: - kimchi_log.warning("Unable to turn on sebool virt_use_sysfs") + wok_log.warning("Unable to turn on sebool virt_use_sysfs") def _attach_pci_device(self, vmid, dev_info): self._validate_pci_passthrough_env() @@ -160,7 +160,7 @@ def _attach_pci_device(self, vmid, dev_info): try: dom.attachDeviceFlags(xmlstr, device_flags) except libvirt.libvirtError: - kimchi_log.error( + wok_log.error( 'Failed to attach host device %s to VM %s: \n%s', pci_info['name'], vmid, xmlstr) raise diff --git a/src/kimchi/model/vmifaces.py b/plugins/kimchi/model/vmifaces.py similarity index 96% rename from src/kimchi/model/vmifaces.py rename to plugins/kimchi/model/vmifaces.py index 893f23fe7..0416e284f 100644 --- a/src/kimchi/model/vmifaces.py +++ b/plugins/kimchi/model/vmifaces.py @@ -17,16 +17,16 @@ # 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 random - import libvirt +import random from lxml import etree, objectify -from kimchi.exception import InvalidParameter, MissingParameter -from kimchi.exception import NotFoundError, InvalidOperation -from kimchi.model.config import CapabilitiesModel -from kimchi.model.vms import DOM_STATE_MAP, VMModel -from kimchi.xmlutils.interface import get_iface_xml +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 def getDHCPLeases(net, mac): diff --git a/src/kimchi/model/vms.py b/plugins/kimchi/model/vms.py similarity index 93% rename from src/kimchi/model/vms.py rename to plugins/kimchi/model/vms.py index 84632875e..5ee8741fc 100644 --- a/src/kimchi/model/vms.py +++ b/plugins/kimchi/model/vms.py @@ -18,39 +18,40 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import copy +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 -import libvirt - -from kimchi import model, vnc -from kimchi.config import READONLY_POOL_TYPE, config -from kimchi.exception import InvalidOperation, InvalidParameter -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.kvmusertests import UserTests -from kimchi.model.config import CapabilitiesModel -from kimchi.model.featuretests import FeatureTests -from kimchi.model.tasks import TaskModel -from kimchi.model.templates import TemplateModel -from kimchi.model.utils import get_ascii_nonascii_name, get_vm_name -from kimchi.model.utils import get_metadata_node, remove_metadata_node -from kimchi.model.utils import set_metadata_node -from kimchi.rollbackcontext import RollbackContext -from kimchi.screenshot import VMScreenshot -from kimchi.utils import add_task, convert_data_size, get_next_clone_name -from kimchi.utils import import_class, kimchi_log, run_setfacl_set_attr -from kimchi.utils import template_name_from_uri -from kimchi.xmlutils.cpu import get_cpu_xml, get_numa_xml -from kimchi.xmlutils.utils import xpath_get_text, xml_item_update -from kimchi.xmlutils.utils import dictize +from wok import vnc +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 .. import model +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 featuretests import FeatureTests +from tasks import TaskModel +from templates import TemplateModel +from utils import get_ascii_nonascii_name, get_vm_name +from utils import get_metadata_node, remove_metadata_node +from utils import set_metadata_node DOM_STATE_MAP = {0: 'nostate', @@ -108,7 +109,7 @@ def create(self, params): t.validate() data = {'name': name, 'template': t, 'graphics': params.get('graphics', {})} - taskid = add_task(u'/vms/%s' % name, self._create_task, + taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task, self.objstore, data) return self.task.lookup(taskid) @@ -135,8 +136,8 @@ def _create_task(self, cb, params): except Exception as e: # It is possible to continue Kimchi executions without store # vm icon info - kimchi_log.error('Error trying to update database with guest ' - 'icon information due error: %s', e.message) + 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. @@ -201,16 +202,20 @@ def __init__(self, **kargs): self.objstore = kargs['objstore'] self.caps = CapabilitiesModel(**kargs) self.vmscreenshot = VMScreenshotModel(**kargs) - self.users = import_class('kimchi.model.users.UsersModel')(**kargs) - self.groups = import_class('kimchi.model.groups.GroupsModel')(**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('kimchi.model.vmsnapshots.VMSnapshotModel') + cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotModel') self.vmsnapshot = cls(**kargs) - cls = import_class('kimchi.model.vmsnapshots.VMSnapshotsModel') + cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotsModel') self.vmsnapshots = cls(**kargs) self.stats = {} @@ -260,16 +265,17 @@ def clone(self, name): task_names = session.get_list('task') for tn in task_names: t = session.get('task', tn) - if t['target_uri'].startswith('/vms/'): - uri_name = t['target_uri'][5:] # 5 = len('/vms/') + 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'/vms/%s/clone' % new_name, self._clone_task, - self.objstore, {'name': name, 'new_name': new_name}) + 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) @@ -413,10 +419,10 @@ def _delete_disk_from_objstore(path): # a new volume with the same size, the pool 'default' should # be used if orig_vol['capacity'] > orig_pool['available']: - kimchi_log.warning('storage pool \'%s\' doesn\'t have ' - 'enough free space to store image ' - '\'%s\'; falling back to \'default\'', - orig_pool_name, path) + 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') @@ -429,9 +435,9 @@ def _delete_disk_from_objstore(path): elif orig_pool['type'] in ['scsi', 'iscsi']: # SCSI and iSCSI always fall back to the storage pool 'default' - kimchi_log.warning('cannot create new volume for clone in ' - 'storage pool \'%s\'; falling back to ' - '\'default\'', orig_pool_name) + 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') @@ -884,7 +890,7 @@ def _update_guest_stats(self, name): except Exception as e: # VM might be deleted just after we get the list. # This is OK, just skip. - kimchi_log.debug('Error processing VM stats: %s', e.message) + 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) @@ -1072,8 +1078,8 @@ def delete(self, name): try: snapshot_names = self.vmsnapshots.get_list(name) except OperationFailed, e: - kimchi_log.error('cannot list snapshots: %s; ' - 'skipping snapshot deleting...' % e.message) + wok_log.error('cannot list snapshots: %s; ' + 'skipping snapshot deleting...' % e.message) else: for s in snapshot_names: self.vmsnapshot.delete(name, s) @@ -1097,8 +1103,8 @@ def delete(self, name): session.delete('storagevolume', path, ignore_missing=True) except libvirt.libvirtError as e: - kimchi_log.error('Unable to get storage volume by path: %s' % - e.message) + wok_log.error('Unable to get storage volume by path: %s' % + e.message) except Exception as e: raise OperationFailed('KCHVOL0017E', {'err': e.message}) @@ -1117,8 +1123,8 @@ def delete(self, name): session.delete('vm', dom.UUIDString(), ignore_missing=True) except Exception as e: # It is possible to delete vm without delete its database info - kimchi_log.error('Error deleting vm information from database: ' - '%s', e.message) + wok_log.error('Error deleting vm information from database: ' + '%s', e.message) vnc.remove_proxy_token(name) @@ -1233,8 +1239,8 @@ def _vmscreenshot_delete(self, vm_uuid): except Exception as e: # It is possible to continue Kimchi executions without delete # screenshots - kimchi_log.error('Error trying to delete vm screenshot from ' - 'database due error: %s', e.message) + 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 @@ -1299,8 +1305,8 @@ def lookup(self, name): except Exception as e: # It is possible to continue Kimchi executions without store # screenshots - kimchi_log.error('Error trying to update database with guest ' - 'screenshot information due error: %s', e.message) + wok_log.error('Error trying to update database with guest ' + 'screenshot information due error: %s', e.message) return img_path @staticmethod @@ -1317,8 +1323,8 @@ def get_screenshot(vm_uuid, objstore, conn): # exception from '__exit__' when calling 'session.store' # It is possible to continue Kimchi vm executions without # screenshots - kimchi_log.error('Error trying to update database with guest ' - 'screenshot information due error: %s', e.message) + wok_log.error('Error trying to update database with guest ' + 'screenshot information due error: %s', e.message) return LibvirtVMScreenshot(params, conn) diff --git a/src/kimchi/model/vmsnapshots.py b/plugins/kimchi/model/vmsnapshots.py similarity index 94% rename from src/kimchi/model/vmsnapshots.py rename to plugins/kimchi/model/vmsnapshots.py index 3a92cdc43..6abf726eb 100644 --- a/src/kimchi/model/vmsnapshots.py +++ b/plugins/kimchi/model/vmsnapshots.py @@ -17,19 +17,19 @@ # 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 time - import libvirt import lxml.etree as ET +import time from lxml import objectify from lxml.builder import E -from kimchi.exception import InvalidOperation, NotFoundError, OperationFailed -from kimchi.model.tasks import TaskModel -from kimchi.model.vms import DOM_STATE_MAP, VMModel -from kimchi.model.vmstorages import VMStorageModel, VMStoragesModel -from kimchi.utils import add_task -from kimchi.xmlutils.utils import xpath_get_text +from wok.exception import InvalidOperation, NotFoundError, OperationFailed +from wok.utils import add_task +from wok.xmlutils.utils import xpath_get_text + +from tasks import TaskModel +from vms import DOM_STATE_MAP, VMModel +from vmstorages import VMStorageModel, VMStoragesModel class VMSnapshotsModel(object): @@ -72,8 +72,8 @@ def create(self, vm_name, params={}): name = params.get('name', unicode(int(time.time()))) task_params = {'vm_name': vm_name, 'name': name} - taskid = add_task(u'/vms/%s/snapshots/%s' % (vm_name, name), - self._create_task, self.objstore, task_params) + 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): diff --git a/src/kimchi/model/vmstorages.py b/plugins/kimchi/model/vmstorages.py similarity index 90% rename from src/kimchi/model/vmstorages.py rename to plugins/kimchi/model/vmstorages.py index 21d4f545e..3aa794cd6 100644 --- a/src/kimchi/model/vmstorages.py +++ b/plugins/kimchi/model/vmstorages.py @@ -18,20 +18,21 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import string - from lxml import etree -from kimchi.exception import InvalidOperation, InvalidParameter, NotFoundError -from kimchi.exception import OperationFailed -from kimchi.model.config import CapabilitiesModel -from kimchi.model.vms import DOM_STATE_MAP, VMModel -from kimchi.model.storagevolumes import StorageVolumeModel -from kimchi.model.utils import get_vm_config_flag -from kimchi.osinfo import lookup -from kimchi.model.diskutils import get_disk_used_by, set_disk_used_by -from kimchi.utils import kimchi_log -from kimchi.xmlutils.disk import get_device_node, get_disk_xml -from kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks +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'] @@ -191,8 +192,8 @@ def delete(self, vm_name, dev_name): if path is not None: used_by = get_disk_used_by(self.objstore, self.conn, path) else: - kimchi_log.error("Unable to decrement volume used_by on" - " delete because no path could be found.") + 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: @@ -202,8 +203,8 @@ def delete(self, vm_name, dev_name): used_by.remove(vm_name) set_disk_used_by(self.objstore, path, used_by) else: - kimchi_log.error("Unable to update %s:%s used_by on delete." - % (vm_name, dev_name)) + 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 @@ -246,6 +247,6 @@ def update(self, vm_name, dev_name, params): set_disk_used_by(self.objstore, new_disk_path, new_disk_used_by) except Exception as e: - kimchi_log.error("Unable to update dev used_by on update due to" - " %s:" % e.message) + wok_log.error("Unable to update dev used_by on update due to" + " %s:" % e.message) return dev diff --git a/src/kimchi/netinfo.py b/plugins/kimchi/netinfo.py similarity index 100% rename from src/kimchi/netinfo.py rename to plugins/kimchi/netinfo.py diff --git a/src/kimchi/network.py b/plugins/kimchi/network.py similarity index 100% rename from src/kimchi/network.py rename to plugins/kimchi/network.py diff --git a/src/kimchi/osinfo.py b/plugins/kimchi/osinfo.py similarity index 94% rename from src/kimchi/osinfo.py rename to plugins/kimchi/osinfo.py index 6a6af8c75..60b112f08 100644 --- a/src/kimchi/osinfo.py +++ b/plugins/kimchi/osinfo.py @@ -21,12 +21,11 @@ import glob import os import psutil - from collections import defaultdict from configobj import ConfigObj from distutils.version import LooseVersion -from kimchi.config import paths +from wok.config import PluginPaths SUPPORTED_ARCHS = {'x86': ('i386', 'i686', 'x86_64'), @@ -84,7 +83,7 @@ icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/' - % paths.ui_dir, 'icon-*.png')] + % PluginPaths('kimchi').ui_dir, 'icon-*.png')] def _get_arch(): @@ -124,7 +123,7 @@ def _get_tmpl_defaults(): default_config = ConfigObj(tmpl_defaults) # Load template configuration file - config_file = os.path.join(paths.conf_dir, 'template.conf') + config_file = os.path.join(PluginPaths('kimchi').conf_dir, 'template.conf') config = ConfigObj(config_file) # Merge default configuration with file configuration @@ -141,7 +140,8 @@ def _get_tmpl_defaults(): # Parse storage section to get storage pool and disks values storage_section = default_config.pop('storage') - defaults['storagepool'] = '/storagepools/' + storage_section.pop('pool') + defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \ + storage_section.pop('pool') defaults['disks'] = [] for disk in storage_section.keys(): data = storage_section[disk] @@ -210,8 +210,8 @@ def lookup(distro, version): params.update(custom_specs.get(distro, {}).get(version, {})) if distro in icon_available_distros: - params['icon'] = 'images/icon-%s.png' % distro + params['icon'] = 'plugins/kimchi/images/icon-%s.png' % distro else: - params['icon'] = 'images/icon-vm.png' + params['icon'] = 'plugins/kimchi/images/icon-vm.png' return params diff --git a/plugins/kimchi/po/LINGUAS b/plugins/kimchi/po/LINGUAS new file mode 100644 index 000000000..3fcb18f0b --- /dev/null +++ b/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/plugins/kimchi/po/Makefile.in.in b/plugins/kimchi/po/Makefile.in.in new file mode 100644 index 000000000..d01fb3196 --- /dev/null +++ b/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 +# +# 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 new file mode 100644 index 000000000..c29a807f3 --- /dev/null +++ b/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@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 new file mode 100644 index 000000000..92eef1ea7 --- /dev/null +++ b/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/plugins/kimchi/po/de_DE.po b/plugins/kimchi/po/de_DE.po new file mode 100644 index 000000000..0d0c3d865 --- /dev/null +++ b/plugins/kimchi/po/de_DE.po @@ -0,0 +1,2506 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: de_DE\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" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Unbekannter Parameter %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "Löschen ist nicht zulässig für %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s implementiert keine Aktualisierungsmethode" + +#, python-format +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" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "Parameter entsprechen nicht der Anforderung im Schema: %(err)s" + +msgid "You don't have permission to perform this operation." +msgstr "" +"Sie verfügen nicht über die Berechtigung zur Ausführung dieser Operation." + +msgid "Datastore is not initiated in the model object." +msgstr "Datenspeicher wird nicht im Modellobjekt initialisiert." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "" +"Task kann aufgrund des folgenden Fehlers nicht gestartet werden: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"Zeitlimit von %(seconds)s Sekunden ist während der Ausführung von Task " +"'%(task)s' abgelaufen." + +#, python-format +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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Geben Sie %(item)s an, um sich bei Kimchi anzumelden" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "" +"Benutzer %(user_id)s mit den angegebenen LDAP-Einstellungen wurde nicht " +"gefunden." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Ungültige LDAP-Konfiguration: %(item)s : %(value)s" + +msgid "Unknown \"_cap\" specified" +msgstr "Unbekanntes Element \"_cap\" angegeben" + +msgid "\"_passthrough\" should be \"true\" or \"false\"" +msgstr "Für \"_passthrough\" muss \"true\" oder \"false\" angegeben werden" + +msgid "\"_passthrough_affected_by\" should be a device name string" +msgstr "" +"Für \"_passthrough_affected_by\" muss eine Einheitennamenszeichenfolge " +"angegeben werden" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "Für \"_available_only\" muss \"true\" oder \"false\" angegeben werden" + +#, 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 Blockeinheiteninformationen 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 "ISO-Datei %(filename)s konnte nicht gefunden werden" + +#, 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 "Beim Prüfen der OS-Informationen des Image ist ein Fehler aufgetreten." + +msgid "No OS information found in given image." +msgstr "Im angegebenen Image wurden keine OS-Informationen gefunden." + +#, python-format +msgid "Unable to read image file %(filename)s" +msgstr "Die Imagedatei %(filename)s konnte nicht gelesen werden" + +#, python-format +msgid "" +"Image file must be an existing file on system. %(filename)s is not a valid " +"input." +msgstr "" +"Bei der Imagedatei muss es sich um eine auf dem System vorhandene Datei " +"handeln. %(filename)s ist nicht gültig Eingabe." + +#, 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 "" +"Virtuelle Maschine %(name)s konnte nicht umbenannt werden. Der Name " +"%(new_name)s ist bereits belegt oder die virtuelle Maschine wurde nicht " +"ausgeschaltet." + +#, 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 "Screenshot wird auf virtueller Maschine %(name)s nicht unterstützt" + +#, 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 aktualisiert 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 zu ausgeschalteter virtueller Maschine %(name)s konnte nicht " +"hergestellt werden." + +msgid "Virtual machine name must be a string without slashes (/)" +msgstr "" +"Name der virtuellen Maschine muss eine Zeichenfolge ohne Schrägstriche (/) " +"sein" + +#, python-format +msgid "Invalid template URI %(value)s specified for virtual machine" +msgstr "Ungültiger Vorlagen-URI %(value)s für virtuelle Maschine angegeben" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for virtual machine" +msgstr "Ungültiger Speicherpool-URI %(value)s für virtuelle Maschine angegeben" + +msgid "Supported virtual machine graphics are Spice or VNC" +msgstr "Unterstützte Grafiken für virtuelle Maschine sind Spice oder VNC" + +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 ausgeschaltet 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 zurückgesetzt werden. Details: " +"%(err)s" + +msgid "User name list must be an array" +msgstr "Benutzernamensliste muss ein Array sein" + +msgid "User name must be a string" +msgstr "Benutzername muss eine Zeichenfolge sein" + +msgid "Group name list must be an array" +msgstr "Gruppennamensliste muss ein Array sein" + +msgid "Group name must be a string" +msgstr "Gruppenname muss eine Zeichenfolge sein" + +#, python-format +msgid "User(s) '%(users)s' do not exist" +msgstr "Benutzer '%(users)s' nicht vorhanden" + +#, python-format +msgid "Group(s) '%(groups)s' do not exist" +msgstr "Gruppe(n) '%(groups)s' nicht vorhanden" + +#, python-format +msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s" +msgstr "" +"Virtuelle Maschine %(name)s konnte nicht heruntergefahren werden. Details: " +"%(err)s" + +msgid "The guest console password must be a string." +msgstr "Das Konsolenkennwort des Gastes muss eine Zeichenfolge sein." + +msgid "The life time for the guest console password must be a number." +msgstr "" +"Die Lebensdauer für das Konsolenkennwort des Gastes muss eine Zahl sein." + +#, python-format +msgid "Virtual machine '%(name)s' must be stopped before cloning it." +msgstr "Die virtuelle Maschine '%(name)s' muss vor dem Klonen gestoppt werden." + +#, python-format +msgid "Insufficient disk space to clone virtual machine '%(name)s'" +msgstr "" +"Nicht genügend Plattenspeicherplatz zum Klonen der virtuellen Maschine " +"'%(name)s' vorhanden" + +#, python-format +msgid "Unable to clone VM '%(name)s'. Details: %(err)s" +msgstr "" +"Virtuelle Maschine '%(name)s' konnte nicht geklont werden. Details: %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "Ungültige Operation für nicht permanente virtuelle Maschine %(name)s" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "" +"Die virtuelle Maschine '%(name)s' kann nicht ausgesetzt werden, weil sie " +"momentan nicht aktiv ist." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "" +"Virtuelle Maschine '%(name)s' konnte nicht ausgesetzt werden. Details: " +"%(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "" +"Die virtuelle Maschine '%(name)s' kann nicht fortgesetzt werden, weil sie " +"nicht angehalten wurde." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "" +"Virtuelle Maschine '%(name)s' konnte nicht fortgesetzt werden. Details: " +"%(err)s" + +msgid "Memory assigned is higher then the maximum allowed in the host." +msgstr "" +"Der zugewiesene Speicher überschreitet den auf dem Host zulässigen " +"Maximalwert." + +#, python-format +msgid "" +"VM '%(name)s' does not support live memory update. Update the memory with " +"the machine offline to enable this feature." +msgstr "" +"Die Live-Speicheraktualisierung wird von der virtuellen Maschine '%(name)s' " +"nicht unterstützt. Aktualisieren Sie den Speicher mit der Maschine im " +"Offlinemodus, um diese Funktion zu aktivieren." + +msgid "Only increase memory is allowed in active VMs" +msgstr "" +"Die Speichervergrößerung ist nur in aktiven virtuellen Maschinen zulässig" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"Für die Live-Speicheraktualisierung muss der neue Speicherwert gleich dem " +"alten Speicherwert plus ein Vielfaches von 1024 Mebibyte sein" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "" +"Auf dem Gast sind nicht genügend freie Slots mit 1024 Mebibyte vorhanden." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"Die libvirt-Version des Hosts unterstützt keine Speichereinheiten. Für " +"libvirt muss >= 1.2.14 angegeben sein" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "Fehler beim Anschließen der Speichereinheit. Details: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "" +"%(name)s kann nicht gestartet werden. Virtuelle Maschine wird bereits " +"ausgeführt." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "" +"%(name)s kann nicht ausgeschaltet werden. Virtuelle Maschine ist " +"ausgeschaltet." + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "" +"%(name)s kann nicht heruntergefahren werden. Virtuelle Maschine ist " +"ausgeschaltet." + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "" +"%(name)s kann nicht zurückgesetzt werden. Virtuelle Maschine ist bereits " +"ausgeschaltet." + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"VM %(vmid)s enthält die direkt zugewiesene Hosteinheit %(dev_name)s nicht." + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"Die Hosteinheit %(dev_name)s darf nicht direkt einer VM zugewiesen werden." + +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 "" +"Keine IOMMU-Gruppen gefunden. Für den Host-PCI-Durchgriff muss die IOMMU-" +"Gruppe ordnungsgemäß funktionieren. Aktivieren Sie Intel VT-d oder AMD IOMMU " +"in Ihrem BIOS und prüfen Sie dann, ob der Kernel mit IOMMU-Unterstützung " +"kompiliert wurde. Fügen Sie Ihrem Kernelparameter für die Intel-CPU " +"intel_iommu=on in /boot/grub2/grub.conf hinzu. Für AMD-CPU müssen Sie " +"iommu=pt iommu=1 hinzufügen." + +msgid "\"name\" should be a device name string" +msgstr "Für \"name\" muss eine Einheitennamenszeichenfolge angegeben werden" + +#, python-format +msgid "" +"The device %(name)s is probably in use by the host. Unable to attach it to " +"the guest." +msgstr "" +"Die Einheit %(name)s wird vermutlich vom Host benutzt. Es kann keine " +"Verbindung der Einheit zum Gast hergestellt werden." + +#, 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 Netz %(network)s, das für die virtuelle Maschine %(name)s angegeben " +"wurde, 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 "MAC-Adresse muss folgendes Format verwenden: FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "" +"MAC-Adresse %(mac)s ist in virtueller Maschine %(name)s bereits vorhanden" + +msgid "Invalid MAC Address" +msgstr "Ungültige MAC-Adresse" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "" +"MAC-Adresse einer aktiven virtuellen Maschine kann nicht geändert werden" + +#, 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 "" +"Netz '%(network)s', das für Vorlage %(template)s angegeben wurde, ist nicht " +"vorhanden" + +#, python-format +msgid "" +"Storage pool %(pool)s specified for template %(template)s does not exist" +msgstr "" +"Speicherpool %(pool)s, der für Vorlage %(template)s angegeben wurde, ist " +"nicht vorhanden" + +#, python-format +msgid "Storage pool %(pool)s specified for template %(template)s is not active" +msgstr "" +"Speicherpool %(pool)s, der für Vorlage %(template)s angegeben wurde, 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 "" +"Netz %(network)s, das für Vorlage %(template)s angegeben wurde, 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 größer als 0 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 oder ein Basisimage 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 "" +"Geben Sie einen Datenträger für eine Vorlage an, wenn der Speicherpool iSCSI " +"oder SCSI ist" + +#, python-format +msgid "The volume %(volume)s is not in storage pool %(pool)s" +msgstr "" +"Der Datenträger %(volume)s ist nicht im Speicherpool %(pool)s vorhanden" + +#, 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 "Plattengröße muss eine Ganzzahl größer als 1 GB sein." + +msgid "Template base image must be a valid local image file" +msgstr "Basisimage der Vorlage muss eine gültige lokale Imagedatei sein" + +#, python-format +msgid "Cannot identify base image %(path)s format" +msgstr "Format für %(path)s des Basisimage kann nicht ermittelt werden" + +msgid "" +"When specifying CPU topology, VCPUs must be a product of sockets, cores, and " +"threads." +msgstr "" +"Bei der Angabe der CPU-Topologie müssen VCPUs ein Produkt der Sockets, Kerne " +"und Threads sein." + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "" +"Bei Angabe der CPU-Topologie muss jedes Element eine Ganzzahl größer als " +"null sein." + +msgid "" +"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, " +"qcow2, qed, raw, vmdk, vpc." +msgstr "" +"Ungültiges Plattenimageformat. Gültige Formate: bochs, cloop, cow, dmg, " +"qcow, qcow2, qed, raw, vmdk, vpc." + +#, 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 "Fehler beim Abrufen der XML für Speicherpool in %(pool)s" + +msgid "Storage pool name must be a string without slashes (/)" +msgstr "" +"Name des Speicherpools muss eine Zeichenfolge ohne Schrägstriche (/) sein" + +msgid "" +"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-" +"iso" +msgstr "" +"Unterstützte Speicherpooltypen sind dir, netfs, logical, iscsi, isci und " +"kimchi-iso" + +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 "Speicherpooleinheit muss den absoluten Pfad zur Blockeinheit angeben" + +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 "Benutzername des iSCSI-Ziels muss eine Zeichenfolge sein" + +msgid "iSCSI target password must be a string" +msgstr "Kennwort des iSCSI-Ziels muss eine Zeichenfolge sein" + +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 "" +"Logischer Pool %(pool)s konnte nicht erweitert werden. Details: %(err)s" + +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 "" +"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 "" +"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 "" +"Speicherdatenträger %(volume)s konnte nicht erstellt werden, weil " +"Speicherpool %(pool)s nicht aktiv ist" + +#, python-format +msgid "Specify %(item)s in order to create storage volume %(volume)s" +msgstr "" +"Geben Sie %(item)s an, um den 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 im Speicherpool %(pool)s nicht erstellt " +"werden. Details: %(err)s" + +#, python-format +msgid "" +"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s" +msgstr "" +"Speicherdatenträger im Speicherpool %(pool)s konnten nicht 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 "" +"Format des Speicherdatenträgers wird nicht unterstützt. Gültige Formate: " +"bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +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 "Der Parameter %(param)s kann nur einmal angegeben werden" + +#, python-format +msgid "Create volume from %(param)s is not supported" +msgstr "Erstellung des Datenträgers aus %(param)s wird nicht unterstützt" + +msgid "Storage volume capacity must be an integer number." +msgstr "Kapazität des Speicherdatenträgers muss eine Ganzzahl sein." + +msgid "Storage volume URL must be http://, https://, ftp:// or ftps://." +msgstr "" +"Speicherdatenträger-URL muss eine http://-, https://-, ftp://- oder ftps://-" +"URL sein." + +#, python-format +msgid "Unable to access file %(url)s. Please, check it." +msgstr "" +"Zugriff auf Datei %(url)s konnte nicht ausgeführt werden. Überprüfen Sie die " +"Datei." + +#, python-format +msgid "" +"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: " +"%(err)s" +msgstr "" +"Speicherdatenträger '%(name)s' im Pool '%(pool)s' konnte nicht geklont " +"werden. Details: %(err)s" + +msgid "Specify chunk data and its size to upload a file." +msgstr "Geben Sie Chunkdaten und deren Größe an, um eine Datei hochzuladen." + +msgid "In order to upload a storage volume, specify the 'upload' parameter." +msgstr "" +"Um einen Speicherdatenträger hochzuladen, müssen Sie den Parameter 'upload' " +"angeben." + +msgid "" +"Unable to upload chunk data as it does not match with requested chunk size." +msgstr "" +"Chunkdaten konnten nicht hochgeladen werden, da sie nicht mit der " +"angeforderten Chunkgröße übereinstimmen." + +#, python-format +msgid "The storage volume %(vol)s is not under an upload process." +msgstr "" +"Der Speicherdatenträger %(vol)s befindet sich nicht in einem Uploadprozess." + +msgid "The upload chunk data will exceed the storage volume size." +msgstr "" +"Die Chunkdaten für den Upload überschreiten die Größe des " +"Speicherdatenträgers." + +#, python-format +msgid "Unable to upload chunk data to storage volume. Details: %(err)s." +msgstr "" +"Chunkdaten konnten nicht auf Speicherdatenträger hochgeladen werden. " +"Details: %(err)s." + +#, 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 Teilnetz %(subnet)s, das für das Netz %(network)s angegeben wurde, ist " +"nicht gültig." + +#, python-format +msgid "Specify a network interface to create bridged network %(name)s" +msgstr "" +"Geben Sie eine Netzschnittstelle an, um das überbrückte 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 Schnittstelle %(iface)s, die für das Netz %(network)s angegeben wurde, " +"ist bereits belegt" + +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 "Schnittstelle %(iface)s ist bereits vorhanden." + +msgid "Network name must be a string without slashes (/) or quotes (\")" +msgstr "" +"Netzname muss eine Zeichenfolge ohne Schrägstriche (/) oder " +"Anführungszeichen (\") sein" + +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 gelöscht werden. Mit diesem Netz sind einige " +"virtuelle Maschinen %(vms)s und/oder Vorlagen verlinkt." + +#, 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. Mit diesem Netz sind einige " +"virtuelle Maschinen %(vms)s und/oder Vorlagen verlinkt." + +#, 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. Überprüfen Sie den " +"Status der physischen Verbindung." + +#, python-format +msgid "Failed to start network %(name)s. Details: %(err)s" +msgstr "Netz %(name)s konnte nicht gestartet werden. Details: %(err)s" + +#, 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 "" +"Ein Debugbericht mit dem angegebenen Namen %(name)s konnte nicht gefunden " +"werden" + +#, 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 "Sie müssen einen Namen für die Debugberichtsdatei angeben." + +msgid "" +"Debug report name must be a string. Only letters, digits, underscore ('_') " +"and hyphen ('-') are allowed." +msgstr "" +"Der Name des Debugberichts muss eine Zeichenfolge sein. Nur Buchstaben, " +"Ziffern, Unterstreichungszeichen ('_') und Bindestriche ('-') sind zulässig." + +#, python-format +msgid "" +"The debug report with specified name \"%(name)s\" already exists. Please use " +"another one." +msgstr "" +"Der Debugbericht mit dem Namen \"%(name)s\" ist bereits vorhanden. Verwenden " +"Sie einen anderen Namen." + +#, 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 im Host nicht 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 "In Konflikt stehende Flagfilter angegeben." + +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 Aktualisierung 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 "Unable to find %(item)s in datastore" +msgstr "%(item)s konnten nicht im Datenspeicher gefunden werden" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "Ungültiger URI %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" +"Zeitlimitüberschreitung bei Ausführung des Befehls '%(cmd)s' nach " +"%(seconds)s Sekunden" + +msgid "Unable to choose a virtual machine name" +msgstr "Name der virtuellen Maschine konnte nicht ausgewählt werden" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Ungültiger Datenwert '%(value)s'" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Ungültige Dateneinheit '%(unit)s'" + +msgid "Invalid storage type. Types supported: 'cdrom', 'disk'" +msgstr "Ungültiger Speichertyp. Unterstützte Typen: 'cdrom', 'disk'" + +#, python-format +msgid "The path '%(value)s' is not a valid local/remote path for the device" +msgstr "" +"Der Pfad '%(value)s' ist kein gültiger lokaler/ferner Pfad für die Einheit" + +msgid "Only CDROM path can be update." +msgstr "Nur der CD-ROM-Pfad kann aktualisiert werden." + +#, python-format +msgid "" +"The storage device %(dev_name)s does not exist in the virtual machine " +"%(vm_name)s" +msgstr "" +"Die Speichereinheit %(dev_name)s ist in der virtuellen Maschine %(vm_name)s" + +#, 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 "Hot Plug für IDE-Einheit nicht unterstützen" + +msgid "" +"Specify type and path or type and pool/volume to add a new virtual machine " +"disk" +msgstr "" +"Geben Sie Typ und Pfad oder Typ und Pool/Datenträger an, um eine neue Platte " +"für eine virtuelle Maschine hinzuzufü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 "Begrenzung von %(limit)s Einheiten bei Controllertyp %(type)s erreicht" + +#, python-format +msgid "Cannot retrieve disk path information for given pool/volume: %(error)s" +msgstr "" +"Plattenpfadinformationen für angegebenen Pool/Datenträger können nicht " +"abgerufen werden: %(error)s" + +msgid "Volume already in use by other virtual machine." +msgstr "" +"Datenträger wird bereits von einer anderen virtuellen Maschine verwendet." + +msgid "" +"Only one of path or pool/volume can be specified to add a new virtual " +"machine disk" +msgstr "" +"Es kann nur ein Pfad oder ein Pool/Datenträger angegeben werden, um eine " +"neue Platte für die virtuelle Maschine hinzuzufügen" + +#, python-format +msgid "" +"Volume chosen with format %(format)s does not fit in the storage type " +"%(type)s" +msgstr "" +"Ausgewählter Datenträger mit Format %(format)s passt nicht in Speichertyp " +"%(type)s" + +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 eine 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 "Spiegelliste für Repository muss eine Zeichenfolge sein" + +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 eine URL sein, die auf die ASCII-Armor-Datei verweist." + +#, 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 "" +"Geben Sie die Basis-URL, die Spiegelliste oder den Metalink des Repositorys " +"an, um ein YUM-Repository zu erstellen oder zu aktualisieren." + +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 "" +"Konfigurationselemente: '%(items)s' werden vom Repository-Manager nicht " +"unterstützt" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "Repository-Metalink muss eine http://-, ftp://- oder file://-URL sein." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "Spiegelliste und Metalink können nicht gleichzeitig angegeben werden." + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "" +"Die virtuelle Maschine '%(vm)s' muss vor dem Erstellen eines Snapshots " +"gestoppt werden." + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Snapshot '%(name)s' kann auf virtueller Maschine '%(vm)s' nicht erstellt " +"werden. Details: %(err)s" + +#, python-format +msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'." +msgstr "" +"Snapshot '%(name)s' ist auf virtueller Maschine '%(vm)s' nicht vorhanden." + +#, python-format +msgid "" +"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Snapshot '%(name)s' kann auf virtueller Maschine '%(vm)s' nicht abgerufen " +"werden. Details: %(err)s" + +#, python-format +msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s" +msgstr "" +"Snapshots können auf virtueller Maschine '%(vm)s' nicht aufgelistet werden. " +"Details: %(err)s" + +#, python-format +msgid "" +"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Snapshot '%(name)s' kann auf virtueller Maschine '%(vm)s' nicht gelöscht " +"werden. Details: %(err)s" + +#, python-format +msgid "" +"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Aktueller Snapshot der virtuellen Maschine '%(vm)s' kann nicht abgerufen " +"werden. Details: %(err)s" + +#, python-format +msgid "" +"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: " +"%(err)s" +msgstr "" +"Virtuelle Maschine '%(vm)s' kann nicht auf Snapshot '%(name)s' zurückgesetzt " +"werden. Details: %(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 "" +"Snapshot der virtuellen Maschine '%(vm)s' kann nicht erstellt werden, weil " +"er eine Platte im Format '%(format)s' enthält. Nur 'qcow2' wird unterstützt." + +msgid "The number of vCPUs is too large for this system." +msgstr "Die Anzahl der vCPUs ist für dieses System zu groß." + +msgid "Invalid vCPU/topology combination." +msgstr "Ungültige Kombination aus vCPU und Topologie." + +msgid "This host (or current configuration) does not allow CPU topology." +msgstr "" +"Dieser Host (oder die aktuelle Konfiguration) erlaubt keine CPU-Topologie." + +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 "Wird erstellt..." + +msgid "Edit Guest" +msgstr "Gast bearbeiten" + +msgid "General" +msgstr "Allgemein" + +msgid "Storage" +msgstr "Speicher" + +msgid "Interface" +msgstr "Schnittstelle" + +msgid "Permission" +msgstr "Berechtigung" + +msgid "Host PCI Device" +msgstr "PCI-Einheit für Host" + +msgid "Snapshot" +msgstr "Snapshot" + +msgid "Name" +msgstr "Name" + +msgid "CPUs" +msgstr "CPUs" + +msgid "Memory (MB)" +msgstr "Speicher (MB)" + +msgid "Icon" +msgstr "Symbol" + +msgid "Device" +msgstr "Einheit" + +msgid "Path" +msgstr "Pfad" + +msgid "Network" +msgstr "Netz" + +msgid "Type" +msgstr "Typ" + +msgid "MAC Address" +msgstr "MAC-Adresse" + +msgid "Available system users and groups" +msgstr "Verfügbare Systembenutzer und -gruppen" + +msgid "Users" +msgstr "Benutzer" + +msgid "Groups" +msgstr "Gruppen" + +msgid "Selected system users and groups" +msgstr "Ausgewählte Systembenutzer und -gruppen" + +msgid "User" +msgstr "Benutzer" + +msgid "All" +msgstr "Alle" + +msgid "To Add" +msgstr "Hinzuzufügen" + +msgid "Added" +msgstr "Hinzugefügt" + +msgid "filter" +msgstr "Filter" + +msgid "Product" +msgstr "Produkt" + +msgid "Vendor" +msgstr "Anbieter" + +msgid "Created" +msgstr "Erstellt" + +msgid "Save" +msgstr "Speichern" + +msgid "Replace" +msgstr "Ersetzen" + +msgid "Detach" +msgstr "Abhängen" + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "LDAP-Benutzer-ID, z. B. foo@foo.com" + +msgid "revert" +msgstr "zurücksetzen" + +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 werden nur \"cdrom\" und \"disk\" unterstützt." + +msgid "Storage Pool" +msgstr "Speicherpool" + +msgid "Storage pool which volume located in" +msgstr "Speicherpool, in dem sich der Datenträger befindet" + +msgid "Storage Volume" +msgstr "Speicherdatenträger" + +msgid "Storage volume to be attached" +msgstr "Anzuhängender Speicherdatenträger" + +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 "Start" +msgstr "Starten" + +msgid "Reset" +msgstr "Zurücksetzen" + +msgid "Pause" +msgstr "Anhalten" + +msgid "Resume" +msgstr "Fortsetzen" + +msgid "Power Off" +msgstr "Ausschalten" + +msgid "Actions" +msgstr "Aktionen" + +msgid "Connect" +msgstr "Verbinden" + +msgid "Clone" +msgstr "Klonen" + +msgid "Edit" +msgstr "Bearbeiten" + +msgid "Shut Down" +msgstr "Herunterfahren" + +msgid "Delete" +msgstr "Löschen" + +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 keine gültige 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 "Datei konnte nicht gelesen werden." + +msgid "Error while uploading file." +msgstr "Fehler beim Hochladen der Datei." + +msgid "Delete Confirmation" +msgstr "Löschbestätigung" + +msgid "OK" +msgstr "OK" + +msgid "Confirm" +msgstr "Bestätigen" + +msgid "Warning" +msgstr "Warnung" + +msgid "Cloning..." +msgstr "Wird geklont..." + +msgid "Loading..." +msgstr "Wird geladen..." + +msgid "An error occurred while retrieving system information." +msgstr "Beim Abrufen der Systeminformationen ist ein Fehler aufgetreten." + +msgid "Retry" +msgstr "Wiederholen" + +msgid "Detailed message:" +msgstr "Detaillierte Meldung:" + +msgid "No ISO found" +msgstr "Keine ISO-Datei gefunden" + +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 "Dieser Vorgang kann lange 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 "Repositories" +msgstr "Repositorys" + +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 "Software Updates" +msgstr "Software-Updates" + +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 "Updateinformationen für Pakete konnten nicht abgerufen werden." + +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 "Debug Reports" +msgstr "Debugberichte" + +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 "" +"Der Berichtsname darf nur Buchstaben, Ziffern, Unterstreichungszeichen ('_') " +"und/oder Bindestriche ('-') enthalten." + +msgid "Pending..." +msgstr "Anstehend..." + +msgid "Report name is the same as the original one." +msgstr "Der Berichtsname stimmt mit dem ursprünglichen Namen überein." + +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 "Ausschalten bestätigen" + +msgid "" +"This action may produce undesirable results, for example unflushed disk " +"cache in the guest. Would you like to continue?" +msgstr "" +"Diese Aktion kann zu nicht gewünschten Ergebnissen führen, beispielsweise zu " +"einem nicht geleerten Plattencache beim Gast. Möchten Sie fortfahren?" + +msgid "Reset Confirmation" +msgstr "Zurücksetzung bestätigen" + +msgid "" +"There is a risk of data loss caused by reset without the guest OS shutdown. " +"Would you like to continue?" +msgstr "" +"Bei einer Zurücksetzung ohne Herunterfahren des Gastbetriebssystems besteht " +"das Risiko eines Datenverlusts. Möchten Sie fortfahren?" + +msgid "Shut Down Confirmation" +msgstr "Herunterfahren bestätigen" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"Hinweis: Diese Anforderung wird vom Gastbetriebssystem möglicherweise " +"ignoriert. Möchten Sie fortfahren?" + +msgid "Virtual Machine delete Confirmation" +msgstr "Löschbestätigung für virtuelle Maschine" + +msgid "" +"This virtual machine is not persistent. Power Off will delete it. Continue?" +msgstr "" +"Diese virtuelle Maschine ist nicht permanent. Wenn Sie das System " +"ausschalten, wird sie gelöscht. Möchten Sie fortfahren?" + +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 "" +"Wenn der Zielgast über SCSI- oder iSCSI-Datenträger verfügt, dann werden sie " +"im Standardspeicherpool geklont. Derselbe Vorgang wird ausgeführt, wenn der " +"Zielpool nicht über genügend Speicherplatz zum Klonen der Datenträger " +"verfügt. Möchten Sie fortfahren?" + +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 "" +"Diese Platte wird dauerhaft abgehängt und Sie können sie neu anhängen. " +"Möchten Sie mit dem Abhängen fortfahren?" + +msgid "interface:" +msgstr "Schnittstelle:" + +msgid "address:" +msgstr "Adresse:" + +msgid "link_type:" +msgstr "Linktyp:" + +msgid "block:" +msgstr "Block:" + +msgid "drive_type:" +msgstr "Laufwerkstyp:" + +msgid "model:" +msgstr "Modell:" + +msgid "Affected devices:" +msgstr "Betroffene Einheiten:" + +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 "" +"Dieses Netz ist nicht permanent. Durch diese Aktion wird es nicht gestoppt, " +"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 "" +"Der überbrückte VLAN-Tag arbeitet möglicherweise nicht korrekt, wenn der " +"Netzmanager aktiviert ist. Sie sollten ihn eventuell inaktivieren." + +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 "iSCSI-Ziele werden geladen..." + +msgid "No iSCSI found. Please input one." +msgstr "iSCSI wurde nicht gefunden. Nehmen Sie die iSCSI-Eingabe vor." + +msgid "Failed to load iSCSI targets." +msgstr "iSCSI-Ziele konnten nicht geladen werden." + +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 "" +"Dies ist kein gültiger Servername oder keine gültige IP. Ändern Sie den " +"Servernamen oder die IP." + +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 "Partitionsinformationen konnten nicht abgerufen werden." + +msgid "In progress..." +msgstr "In Bearbeitung..." + +msgid "Failed!" +msgstr "Fehlgeschlagen!" + +msgid "CDROM path needs to be a valid local/remote path and cannot be blank." +msgstr "" +"Der CD-ROM-Pfad muss ein gültiger lokaler/ferner Pfad sein. Er darf nicht " +"leer sein." + +msgid "Disk pool or volume cannot be blank." +msgstr "Der Plattenpool oder Datenträger darf nicht leer sein." + +msgid "Peers" +msgstr "Peers" + +msgid "Searching" +msgstr "Suche wird durchgeführt" + +msgid "No peers found." +msgstr "Keine Peers gefunden." + +msgid "Help" +msgstr "Hilfe" + +msgid "About" +msgstr "Informationen" + +msgid "Log out" +msgstr "Abmelden" + +msgid "Version:" +msgstr "Version:" + +msgid "Session timeout, please re-login." +msgstr "Sitzungszeitlimitüberschreitung, melden Sie sich erneut an." + +msgid "User Name" +msgstr "Benutzername" + +msgid "Password" +msgstr "Kennwort" + +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 angegeben wird. Wenn kein Name angegeben wird, " +"wird ein Name gewählt auf Basis der aktuellen Uhrzeit ausgewählt. Der Name " +"kann Buchstaben, Ziffern, Unterstreichungszeichen (\"_\") und Bindestriche " +"(\"-\") enthalten." + +msgid "Rename a Debug Report" +msgstr "Debugbericht umbenennen" + +msgid "" +"The name used to identify the report. Name can contain: letters, digits and " +"hyphen (\"-\")." +msgstr "" +"Der Name, mit dem der Bericht angegeben wird. Der Name kann Buchstaben, " +"Ziffern und Bindestriche (\"-\") enthalten." + +msgid "Submit" +msgstr "Übergeben" + +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 "Add a Volume to Storage Pool" +msgstr "Datenträger zu Speicherpool hinzufügen" + +msgid "Fetch from remote URL" +msgstr "Über Remote URL abrufen" + +msgid "Enter the remote URL here." +msgstr "Remote URL hier eingeben." + +msgid "Upload a file" +msgstr "Datei hochladen" + +msgid "Choose the file you want to upload." +msgstr "Wählen Sie die hochzuladende Datei aus." + +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 "Device path" +msgstr "Einheitenpfad" + +msgid "iSCSI Server" +msgstr "iSCSI-Server" + +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 "Server" +msgstr "Server" + +msgid "Port" +msgstr "Port" + +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 "SCSI Adapter" +msgstr "SCSI-Adapter" + +msgid "Please, wait..." +msgstr "Bitte warten..." + +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 "Lokale Imagedatei" + +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 "File Path:" +msgstr "Dateipfad:" + +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 eine benutzerdefinierte URL verwenden" + +msgid "Edit Template" +msgstr "Vorlage bearbeiten" + +msgid "Processor" +msgstr "Prozessor" + +msgid "CDROM" +msgstr "CD-ROM" + +msgid "Image File" +msgstr "Imagedatei" + +msgid "Graphics" +msgstr "Grafik" + +msgid "Disk(GB)" +msgstr "Festplatte (GB)" + +msgid "Disk Format" +msgstr "Plattenformat" + +msgid "CPU Number" +msgstr "CPU-Anzahl" + +msgid "Manually set CPU topology" +msgstr "CPU-Topologie manuell festlegen" + +msgid "Cores" +msgstr "Kerne" + +msgid "Threads" +msgstr "Threads" + +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 "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 "CPU(s)" +msgstr "CPU(s)" + +msgid "System Statistics" +msgstr "Systemstatistik" + +msgid "Update Progress" +msgstr "Aktualisierungsfortschritt" + +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 "Der Name darf weder '/' noch '\"' enthalten." + +msgid "Isolated: no external network connection" +msgstr "Isoliert: keine externe 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 "(Keine Schnittstellen gefunden)" + +msgid "Destination" +msgstr "Zieladresse" + +msgid "Enable VLAN" +msgstr "VLAN aktivieren" + +msgid "VLAN ID" +msgstr "VLAN-ID" + +msgid "Stop" +msgstr "Stoppen" + +msgid "%Used" +msgstr "%Belegt" + +msgid "Location" +msgstr "Position" + +msgid "Capacity" +msgstr "Kapazität" + +msgid "Allocated" +msgstr "Zugeordnet" + +msgid "active" +msgstr "aktiv" + +msgid "inactive" +msgstr "inaktiv" + +msgid "Deactivate" +msgstr "Inaktivieren" + +msgid "Activate" +msgstr "Aktivieren" + +msgid "Add Volume" +msgstr "Datenträger hinzufügen" + +msgid "Extend" +msgstr "Erweitern" + +msgid "Undefine" +msgstr "Definition aufheben" + +msgid "Format" +msgstr "Format" + +msgid "Allocation" +msgstr "Zuordnung" + +msgid "No templates found." +msgstr "Keine Vorlagen gefunden." diff --git a/plugins/kimchi/po/en_US.po b/plugins/kimchi/po/en_US.po new file mode 100644 index 000000000..4e298dbe9 --- /dev/null +++ b/plugins/kimchi/po/en_US.po @@ -0,0 +1,2188 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: en_US\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" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "" + +#, python-format +msgid "Create is not allowed for %(resource)s" +msgstr "" + +msgid "Unable to parse JSON request" +msgstr "" + +msgid "This API only supports JSON" +msgstr "" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "" + +msgid "You don't have permission to perform this operation." +msgstr "" + +msgid "Datastore is not initiated in the model object." +msgstr "" + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" + +#, python-format +msgid "Authentication failed for user '%(username)s'. [Error code: %(code)s]" +msgstr "" + +msgid "You are not authorized to access Kimchi" +msgstr "" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "" + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +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 "" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +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 "" + +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 "Cannot start %(name)s. Virtual machine is already running." +msgstr "" + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "" + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "" + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +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 "Unable to find %(item)s in datastore" +msgstr "" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" + +msgid "Unable to choose a virtual machine name" +msgstr "" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +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 "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 "Users" +msgstr "" + +msgid "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 "Cancel" +msgstr "" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "" + +msgid "revert" +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 "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 "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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "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 "" + +msgid "User Name" +msgstr "" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "" + +msgid "iSCSI Server" +msgstr "" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "" + +msgid "Server" +msgstr "" + +msgid "Port" +msgstr "" + +msgid "Target" +msgstr "" + +msgid "The iSCSI target on iSCSI server" +msgstr "" + +msgid "Add iSCSI Authentication" +msgstr "" + +msgid "iSCSI Authentication" +msgstr "" + +msgid "SCSI Adapter" +msgstr "" + +msgid "Please, wait..." +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 "File Path:" +msgstr "" + +msgid "Loading default remote ISOs ..." +msgstr "" + +msgid "Arch: " +msgstr "" + +msgid "I want to use a custom URL" +msgstr "" + +msgid "Edit Template" +msgstr "" + +msgid "Processor" +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 "CPU" +msgstr "" + +msgid "Disk I/O" +msgstr "" + +msgid "Network I/O" +msgstr "" + +msgid "Livetile" +msgstr "" + +msgid "No guests found." +msgstr "" + +msgid "Shut down" +msgstr "" + +msgid "Restart" +msgstr "" + +msgid "Basic Information" +msgstr "" + +msgid "OS Distro" +msgstr "" + +msgid "OS Code Name" +msgstr "" + +msgid "CPU(s)" +msgstr "" + +msgid "System Statistics" +msgstr "" + +msgid "Update Progress" +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 "%Used" +msgstr "" + +msgid "Location" +msgstr "" + +msgid "Capacity" +msgstr "" + +msgid "Allocated" +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 "No templates found." +msgstr "" diff --git a/plugins/kimchi/po/es_ES.po b/plugins/kimchi/po/es_ES.po new file mode 100644 index 000000000..eddb11c2c --- /dev/null +++ b/plugins/kimchi/po/es_ES.po @@ -0,0 +1,2498 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: es_ES\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" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Parámetro %(value)s desconocido" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "No se permite la supresión para %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s no implementa el método de actualización" + +#, python-format +msgid "Create is not allowed for %(resource)s" +msgstr "No se permite la creación 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" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "Los parámetros no coinciden con el requisito en el esquema: %(err)s" + +msgid "You don't have permission to perform this operation." +msgstr "No dispone de permiso para llevar a cabo esta operación." + +msgid "Datastore is not initiated in the model object." +msgstr "El almacén de datos no se ha iniciado en el objeto de modelo." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "No se puede iniciar la tarea debido a un error: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"El tiempo de espera de %(seconds)s segundos se ha agotado al ejecutar la " +"tarea '%(task)s." + +#, python-format +msgid "Authentication failed for user '%(username)s'. [Error code: %(code)s]" +msgstr "" +"Error en la autenticación 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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Especifique %(item)s para iniciar sesión en Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "" +"No se ha encontrado el usuario %(user_id)s con los valores LDAP indicados." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Configuración LDAP no válida: %(item)s : %(value)s" + +msgid "Unknown \"_cap\" specified" +msgstr "Se ha especificado un valor \"_cap\" desconocido" + +msgid "\"_passthrough\" should be \"true\" or \"false\"" +msgstr "\"_passthrough\" debería ser \"true\" o \"false\"" + +msgid "\"_passthrough_affected_by\" should be a device name string" +msgstr "" +"\"_passthrough_affected_by\" debería ser una cadena de nombre de dispositivo" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\" debería ser \"true\" o \"false\"" + +#, python-format +msgid "Error while getting block devices. Details: %(err)s" +msgstr "Error al obtener dispositivos de bloque. Detalles: %(err)s" + +#, python-format +msgid "Error while getting block device information for %(device)s." +msgstr "" +"Error al obtener información de dispositivos de bloque para %(device)s." + +#, python-format +msgid "Unable to find distro file: %(filename)s" +msgstr "No se ha podido 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 ha podido analizar el archivo distro: %(filename)s. Asegúrese de que " +"se trate de un archivo JSON. " + +#, python-format +msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s" +msgstr "" +"No se puede iniciar sesión en el %(portal)s de 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 sesión en el host iSCSI %(host)s de destino %(target)s" + +#, python-format +msgid "Unable to find ISO file %(filename)s" +msgstr "No se puede encontrar el archivo ISO %(filename)s" + +#, python-format +msgid "The ISO file %(filename)s is not bootable" +msgstr "El archivo ISO %(filename)s no se puede arrancar" + +#, 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 El Torito válido" + +#, python-format +msgid "Invalid El Torito validation entry in ISO %(filename)s" +msgstr "La entrada de validación de El Torito no es válida en ISO %(filename)s" + +#, python-format +msgid "Invalid El Torito boot indicator in ISO %(filename)s" +msgstr "El indicador de arranque de El Torito no es 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 erróneo al leer el descriptor de volúmenes 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 " +"las listas de control de acceso de archivos 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 "" +"Se ha producido un error al analizar la información de sistema operativo de " +"las imágenes. " + +msgid "No OS information found in given image." +msgstr "" +"No se ha encontrado información de sistema operativo en una imagen " +"especificada. " + +#, python-format +msgid "Unable to read image file %(filename)s" +msgstr "No se puede leer el archivo de imágenes %(filename)s" + +#, python-format +msgid "" +"Image file must be an existing file on system. %(filename)s is not a valid " +"input." +msgstr "" +"El archivo de imágenes debe ser un archivo existente en el sistema. " +"%(filename)s no es una entrada válida. " + +#, python-format +msgid "Virtual machine %(name)s already exists" +msgstr "Ya existe la máquina virtual %(name)s" + +#, python-format +msgid "Virtual machine %(name)s does not exist" +msgstr "No existe la máquina virtual %(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 "" +"No se puede renombrar la máquina virtual %(name)s. El nombre %(new_name)s ya " +"se está utilizando o la máquina virtual no se ha apagado. " + +#, 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 "No se acepta la captura de pantalla en la máquina virtual %(name)s" + +#, 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 actualizar 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 "No se puede conectar a la máquina virtual %(name)s apagada. " + +msgid "Virtual machine name must be a string without slashes (/)" +msgstr "" +"El nombre de la máquina virtual debe ser una serie sin barras inclinadas (/)" + +#, python-format +msgid "Invalid template URI %(value)s specified for virtual machine" +msgstr "" +"Se ha especificado un URI de plantilla %(value)s no válido para la máquina " +"virtual" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for virtual machine" +msgstr "" +"Se ha especificado un URI de agrupación de almacenamiento %(value)s no " +"válido para la máquina virtual" + +msgid "Supported virtual machine graphics are Spice or VNC" +msgstr "Los gráficos de la máquina virtual soportados son Spice o VNC" + +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 apagar 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 restablecer la máquina virtual %(name)s. Detalles: %(err)s" + +msgid "User name list must be an array" +msgstr "La lista de nombres de usuarios debe ser una matriz" + +msgid "User name must be a string" +msgstr "El nombre de usuario debe ser una serie" + +msgid "Group name list must be an array" +msgstr "La lista de nombres de grupos debe ser una matriz" + +msgid "Group name must be a string" +msgstr "El nombre de grupo debe ser una serie" + +#, python-format +msgid "User(s) '%(users)s' do not exist" +msgstr "No existe el usuario (o usuarios) '%(users)s'" + +#, python-format +msgid "Group(s) '%(groups)s' do not exist" +msgstr "No existe el grupo (o grupos) '%(groups)s'" + +#, python-format +msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s" +msgstr "No se puede apagar la máquina virtual %(name)s. Detalles: %(err)s" + +msgid "The guest console password must be a string." +msgstr "La contraseña de la consola del invitado debe ser una serie. " + +msgid "The life time for the guest console password must be a number." +msgstr "" +"El tiempo de vida para la contraseña de la consola del invitado debe ser un " +"número. " + +#, python-format +msgid "Virtual machine '%(name)s' must be stopped before cloning it." +msgstr "La máquina virtual '%(name)s' se debe detener antes de clonarla." + +#, python-format +msgid "Insufficient disk space to clone virtual machine '%(name)s'" +msgstr "" +"No hay espacio de disco suficiente para clonar la máquina virtual '%(name)s'" + +#, python-format +msgid "Unable to clone VM '%(name)s'. Details: %(err)s" +msgstr "No se puede clonar la máquina virtual '%(name)s'. Detalles: %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "Operación no válida para la máquina virtual no persistente %(name)s" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "" +"No se puede suspender la máquina virtual '%(name)s' porque no se está " +"ejecutando." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "No se puede suspender la máquina virtual '%(name)s'. Detalles: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "" +"No se puede reanudar la máquina virtual '%(name)s' porque no se ha puesto en " +"pausa. " + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "No se puede reanudar la máquina virtual '%(name)s'. Detalles: %(err)s" + +msgid "Memory assigned is higher then the maximum allowed in the host." +msgstr "La memoria asignada es superior al máximo asignado en el host." + +#, python-format +msgid "" +"VM '%(name)s' does not support live memory update. Update the memory with " +"the machine offline to enable this feature." +msgstr "" +"La máquina virtual '%(name)s' no admite la actualización de memoria activa. " +"Actualice la memoria con la máquina fuera de línea para habilitar esta " +"característica. " + +msgid "Only increase memory is allowed in active VMs" +msgstr "" +"Solamente se permite aumentar la memoria en las máquinas virtuales activas" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"Para la actualización de memoria en directo, el valor de memoria nuevo debe " +"ser igual al valor anterior de la memoria más múltiplos de 1024 Mib" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "No hay suficientes ranuras libres de 1024 Mib en el invitado. " + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"La versión libvirt del host no admite dispositivos de memoria. Libvirt debe " +"ser >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "Error al conectar el dispositivo de memoria. Detalles: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "No se puede iniciar %(name)s. La máquina virtual ya está en ejecución." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "No se puede apagar %(name)s. La máquina virtual está apagada." + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "No se puede apagar %(name)s. La máquina virtual está apagada." + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "No se puede restablecer %(name)s. La máquina virtual ya está apagada." + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"La máquina virtual %(vmid)s no contiene el dispositivo de host asignado " +"directamente %(dev_name)s." + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"El dispositivo de host %(dev_name)s no se permite para asignarlo " +"directamente a la máquina virtual. " + +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 "" +"No se han encontrado grupos IOMMU. El paso a través de PCI de host necesita " +"el grupo IOMMU para funcionar correctamente. Habilite Intel VT-d o AMD IOMMU " +"en el BIOS y, a continuación, verifique que el Kernel se ha compilado con " +"soporte IOMMU. Para Intel CPU, añada intel_iommu=on al parámetro de Kernel " +"en /boot/grub2/grub.conf. Para AMD CPU, añada iommu=pt iommu=1." + +msgid "\"name\" should be a device name string" +msgstr "\"name\" debe ser una serie de nombre de dispositivo" + +#, python-format +msgid "" +"The device %(name)s is probably in use by the host. Unable to attach it to " +"the guest." +msgstr "" +"El dispositivo %(name)s lo está utilizando probablemente el host. No se " +"puede conectar al invitado. " + +#, 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 "La dirección MAC debe respetar este formato FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "La dirección MAC %(mac)s ya existe en la máquina virtual %(name)s" + +msgid "Invalid MAC Address" +msgstr "Dirección MAC no válida" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "" +"No se puede cambiar la dirección MAC de una máquina virtual en ejecución" + +#, 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 que se ha especificado 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 CPU debe ser un entero mayor que 0" + +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 "" +"Se ha especificado un URI de agrupación de almacenamiento %(value)s no " +"válido para la plantilla" + +msgid "Specify an ISO image as CDROM or a base image to create a template" +msgstr "" +"Especifique una imagen ISO como CDROM o una imagen base 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 "" +"Especifique un volumen para una plantilla cuando la agrupación de " +"almacenamiento sea iSCSI o SCSI" + +#, python-format +msgid "The volume %(volume)s is not in storage pool %(pool)s" +msgstr "" +"El volumen %(volume)s no se halla en la agrupación de almacenamiento %(pool)s" + +#, python-format +msgid "Unable to create template due error: %(err)s" +msgstr "No se ha podido crear la plantilla debido al error: %(err)s" + +#, python-format +msgid "Unable to delete template due error: %(err)s" +msgstr "No se ha podido suprimir la plantilla debido a un error: %(err)s" + +msgid "Disk size must be an integer greater than 1GB." +msgstr "El tamaño del disco debe ser un entero mayor que 1 GB." + +msgid "Template base image must be a valid local image file" +msgstr "" +"La imagen base de la plantilla debe ser un archivo de imagen base local " +"válido" + +#, python-format +msgid "Cannot identify base image %(path)s format" +msgstr "No se puede identificar el formato de la imagen base %(path)s" + +msgid "" +"When specifying CPU topology, VCPUs must be a product of sockets, cores, and " +"threads." +msgstr "" +"Cuando se especifique la topología de CPU, las VCPU deben ser un producto de " +"sockets, núcleos y hebras. " + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "" +"Cuando se especifica la topología de CPU, cada elemento debe ser un entero " +"mayor que cero." + +msgid "" +"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, " +"qcow2, qed, raw, vmdk, vpc." +msgstr "" +"formato de imagen de disco no válido. Formatos válidos: bochs, cloop, cow, " +"dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +#, python-format +msgid "Storage pool %(name)s already exists" +msgstr "Ya existe la agrupación de almacenamiento %(name)s" + +#, python-format +msgid "Storage pool %(name)s does not exist" +msgstr "No existe la agrupación de almacenamiento %(name)s" + +#, python-format +msgid "Specify %(item)s in order to create the storage pool %(name)s" +msgstr "" +"Especifique %(item)s para 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 activo %(name)s" + +#, python-format +msgid "Unable to list storage pools. Details: %(err)s" +msgstr "" +"No se pueden listar las 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 ha fallado el montaje de la " +"vía de acceso de exportación %(path)s" + +#, python-format +msgid "Unsupported storage pool type: %(type)s" +msgstr "Tipo de agrupación de almacenamiento no admitido: %(type)s" + +#, python-format +msgid "Error while retrieving storage pool XML to %(pool)s" +msgstr "" +"Error al recuperar el XML de la agrupación de almacenamiento en %(pool)s" + +msgid "Storage pool name must be a string without slashes (/)" +msgstr "" +"El nombre de la agrupación de almacenamiento debe ser una serie sin barras " +"inclinadas (/)" + +msgid "" +"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-" +"iso" +msgstr "" +"Los tipos de agrupación de almacenamiento admitidos son dir, netfs, logical, " +"iscsi, isci y kimchi-iso" + +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 "" +"El dispositivo de la agrupación de almacenamiento debe ser la vía de acceso " +"absoluta al dispositivo de bloque" + +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 "El nombre de usuario de destino de iSCSI debe ser una serie" + +msgid "iSCSI target password must be a string" +msgstr "La contraseña de destino de iSCSI debe ser una serie" + +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 válido. 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 "No se puede ampliar la agrupación lógica %(pool)s. Detalles: %(err)s" + +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 "" +"Ya existe un grupo de volúmenes denominado '%(name)s'. 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 "Ya existe el volumen de almacenamiento %(name)s" + +#, python-format +msgid "Storage volume %(name)s does not exist in storage pool %(pool)s" +msgstr "" +"No existe el volumen de almacenamiento %(name)s 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 "" +"No se puede crear el volumen de almacenamiento %(volume)s porque la " +"agrupación de almacenamiento %(pool)s no está activa" + +#, python-format +msgid "Specify %(item)s in order to create storage volume %(volume)s" +msgstr "" +"Especifique %(item)s para 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 los 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 limpiar 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 admite la creación y supresión del " +"volumen" + +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 "" +"Formato de volumen de almacenamiento no admitido. Formatos válidos: bochs, " +"cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +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 del volumen de " +"almacenamiento debido a un error: %(err)s" + +#, python-format +msgid "Only one of parameter %(param)s can be specified" +msgstr "Sólo se puede especificar uno de los parámetros %(param)s" + +#, python-format +msgid "Create volume from %(param)s is not supported" +msgstr "No se admite la creación del volumen de %(param)s" + +msgid "Storage volume capacity must be an integer number." +msgstr "La capacidad del volumen de almacenamiento debe ser un número entero. " + +msgid "Storage volume URL must be http://, https://, ftp:// or ftps://." +msgstr "" +"El URL del volumen de almacenamiento debe ser http://, https://, ftp:// o " +"ftps://." + +#, python-format +msgid "Unable to access file %(url)s. Please, check it." +msgstr "No se puede acceder al archivo %(url)s. Por favor, compruébelo. " + +#, python-format +msgid "" +"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: " +"%(err)s" +msgstr "" +"No se puede clonar el volumen de almacenamiento '%(name)s' en la agrupación " +"'%(pool)s'. Detalles: %(err)s" + +msgid "Specify chunk data and its size to upload a file." +msgstr "Especifique datos de fragmento y su tamaño para cargar un archivo. " + +msgid "In order to upload a storage volume, specify the 'upload' parameter." +msgstr "" +"Para cargar un volumen de almacenamiento, especifique el parámetro 'upload'. " + +msgid "" +"Unable to upload chunk data as it does not match with requested chunk size." +msgstr "" +"No se pueden cargar datos de fragmento porque no coinciden con el tamaño de " +"fragmento solicitado. " + +#, python-format +msgid "The storage volume %(vol)s is not under an upload process." +msgstr "" +"El volumen de almacenamiento %(vol)s no está bajo un proceso de carga. " + +msgid "The upload chunk data will exceed the storage volume size." +msgstr "" +"Los datos de fragmento de carga superarán el tamaño del volumen de " +"almacenamiento. " + +#, python-format +msgid "Unable to upload chunk data to storage volume. Details: %(err)s." +msgstr "" +"No se pueden cargar datos de fragmento al volumen de almacenamiento. " +"Detalles: %(err)s." + +#, python-format +msgid "Interface %(name)s does not exist" +msgstr "No existe la interfaz %(name)s" + +#, python-format +msgid "Network %(name)s already exists" +msgstr "Ya existe la red %(name)s" + +#, python-format +msgid "Network %(name)s does not exist" +msgstr "No existe la red %(name)s" + +#, 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 se está " +"utilizando" + +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 "" +"El nombre de red debe ser una serie sin barras inclinadas (/) ni comillas " +"(\")" + +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 en 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 ha podido 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 ha podido 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 "No se ha podido iniciar la red %(name)s. Detalles: %(err)s" + +#, 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 "" +"No se puede encontrar ningún informe de depuración con el nombre indicado " +"%(name)s" + +#, 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 "Debería dar un nombre al archivo de informe de depuración." + +msgid "" +"Debug report name must be a string. Only letters, digits, underscore ('_') " +"and hyphen ('-') are allowed." +msgstr "" +"El nombre del informe de depuración debe ser una serie. Solamente se " +"permiten letras, dígitos, carácter de subrayado ('_') y guión ('-'). " + +#, python-format +msgid "" +"The debug report with specified name \"%(name)s\" already exists. Please use " +"another one." +msgstr "" +"El informe de depuración con el nombre especificado \"%(name)s\" ya existe. " +"Utilice otro." + +#, python-format +msgid "Storage server %(server)s was not used by Kimchi" +msgstr "El servidor de almacenamiento %(server)s no lo ha utilizado Kimchi" + +#, python-format +msgid "Distro '%(name)s' does not exist" +msgstr "No existe Distro '%(name)s'" + +#, 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 encuentra el dispositivo de nodos '%(name)s'" + +msgid "Conflicting flag filters specified." +msgstr "Se han especificado filtros de distintivos en conflicto." + +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 se ha marcado para actualizarlo." + +#, python-format +msgid "Error while getting packages marked to be updated. Details: %(err)s" +msgstr "" +"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 "Unable to find %(item)s in datastore" +msgstr "No se puede encontrar %(item)s en el almacén de datos" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "URI %(uri)s no válido" + +#, python-format +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 "Unable to choose a virtual machine name" +msgstr "No se puede elegir un nombre de máquina virtual" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Valor de datos '%(value)s' no válido" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Unidad de datos '%(unit)s' no válida" + +msgid "Invalid storage type. Types supported: 'cdrom', 'disk'" +msgstr "Tipo de almacenamiento no válido. Tipos soportados: 'cdrom', 'disk'" + +#, python-format +msgid "The path '%(value)s' is not a valid local/remote path for the device" +msgstr "" +"La vía de acceso '%(value)s' no es una vía de acceso local/remota válida " +"para el dispositivo" + +msgid "Only CDROM path can be update." +msgstr "Solamente se puede actualizar la vía de acceso de CDROM. " + +#, python-format +msgid "" +"The storage device %(dev_name)s does not exist in the virtual machine " +"%(vm_name)s" +msgstr "" +"El dispositivo de almacenamiento %(dev_name)s no existe en la máquina " +"virtual. %(vm_name)s" + +#, python-format +msgid "Error while creating new storage device: %(error)s" +msgstr "Error al crear el dispositivo de almacenamiento nuevo: %(error)s" + +#, python-format +msgid "Error while updating storage device: %(error)s" +msgstr "Error al actualizar el dispositivo de almacenamiento: %(error)s" + +#, python-format +msgid "Error while removing storage device: %(error)s" +msgstr "Error al eliminar el dispositivo de almacenamiento: %(error)s" + +msgid "Do not support IDE device hot plug" +msgstr "No se admite la conexión en caliente del IDE" + +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 y la agrupación/volumen para añadir " +"un nuevo disco de máquina virtual" + +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 "" +"Se ha alcanzado el límite de tipo de controlador %(type)s de %(limit)s " +"dispositivos" + +#, python-format +msgid "Cannot retrieve disk path information for given pool/volume: %(error)s" +msgstr "" +"No se puede recuperar la información de vía de acceso de disco para la " +"agrupación o el volumen que se ha especificado: %(error)s" + +msgid "Volume already in use by other virtual machine." +msgstr "El volumen ya lo está utilizando otra máquina virtual. " + +msgid "" +"Only one of path or pool/volume can be specified to add a new virtual " +"machine disk" +msgstr "" +"Solo se puede especificar uno de vía de acceso o agrupación/volumen para " +"añadir un nuevo disco de máquina virtual" + +#, python-format +msgid "" +"Volume chosen with format %(format)s does not fit in the storage type " +"%(type)s" +msgstr "" +"El volumen elegido con el formato %(format)s no se ajusta al tipo de " +"almacenamiento%(type)s" + +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 "La lista de duplicados en el repositorios debe ser una serie" + +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 puede 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 "" +"Especifique el URL base de repositorio, la lista de duplicados o el " +"metaenlace para crear o actualizar un repositorio YUM. " + +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 escribir en 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 los repositorios. Detalles: '%(err)s'" + +#, python-format +msgid "Unable to retrieve repository information. Details: '%(err)s'" +msgstr "No se puede recuperar información de repositorios. 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 "" +"Elementos de configuración: el gestor de repositorios no admite '%(items)s'" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "" +"El metaenlace de repositorio debe ser http://, ftp:// o el archivo:// URL." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "" +"No se puede especificar la lista de duplicados y el metaenlace a la vez. " + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "" +"Se ha de detener la máquina virtual '%(vm)s' antes de crear una instantánea " +"de la misma. " + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"No se puede crear la instantánea '%(name)s' en la máquina virtual '%(vm)s'. " +"Detalles: %(err)s" + +#, python-format +msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'." +msgstr "La instantánea '%(name)s' no existe en la máquina virtual '%(vm)s'." + +#, python-format +msgid "" +"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"No se puede recuperar la instantánea '%(name)s' en la máquina virtual " +"'%(vm)s'. Detalles: %(err)s" + +#, python-format +msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s" +msgstr "" +"No se pueden listar las instantáneas en la máquina virtual '%(vm)s'. " +"Detalles: %(err)s" + +#, python-format +msgid "" +"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"No se puede suprimir la instantánea '%(name)s' en la máquina virtual " +"'%(vm)s'. Detalles: %(err)s" + +#, python-format +msgid "" +"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"No se puede recuperar la instantánea actual de la máquina virtual '%(vm)s'. " +"Detalles: %(err)s" + +#, python-format +msgid "" +"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: " +"%(err)s" +msgstr "" +"No se puede revertir la máquina virtual '%(vm)s' en la instantánea " +"'%(name)s'. Detalles: %(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 "" +"No se puede crear la instantánea de la máquina virtual '%(vm)s' porque " +"contiene un disco con el formato '%(format)s'; sólo se admite 'qcow2'. " + +msgid "The number of vCPUs is too large for this system." +msgstr "El número de vCPUs es demasiado grande para este sistema. " + +msgid "Invalid vCPU/topology combination." +msgstr "Combinación de vCPU/topología no válida." + +msgid "This host (or current configuration) does not allow CPU topology." +msgstr "Este host (o la configuración actual) no permite la topología de CPU. " + +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 "Creando..." + +msgid "Edit Guest" +msgstr "Editar invitado" + +msgid "General" +msgstr "General" + +msgid "Storage" +msgstr "Almacenamiento" + +msgid "Interface" +msgstr "Interfaz" + +msgid "Permission" +msgstr "Permiso" + +msgid "Host PCI Device" +msgstr "Dispositivo PCI de host" + +msgid "Snapshot" +msgstr "Instantánea" + +msgid "Name" +msgstr "Nombre" + +msgid "CPUs" +msgstr "CPUs" + +msgid "Memory (MB)" +msgstr "Memoria (MB)" + +msgid "Icon" +msgstr "Icono" + +msgid "Device" +msgstr "Dispositivo" + +msgid "Path" +msgstr "Vía de acceso" + +msgid "Network" +msgstr "Red" + +msgid "Type" +msgstr "Tipo" + +msgid "MAC Address" +msgstr "Dirección MAC" + +msgid "Available system users and groups" +msgstr "Usuarios y grupos del sistema disponibles" + +msgid "Users" +msgstr "Usuarios" + +msgid "Groups" +msgstr "Grupos" + +msgid "Selected system users and groups" +msgstr "Usuarios y grupos del sistema seleccionados" + +msgid "User" +msgstr "Usuario" + +msgid "All" +msgstr "Todo" + +msgid "To Add" +msgstr "A añadir" + +msgid "Added" +msgstr "Añadido" + +msgid "filter" +msgstr "filtrar" + +msgid "Product" +msgstr "Producto" + +msgid "Vendor" +msgstr "Proveedor" + +msgid "Created" +msgstr "Creado" + +msgid "Save" +msgstr "Guardar" + +msgid "Replace" +msgstr "Sustituir" + +msgid "Detach" +msgstr "Desconectar" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "ID de usuario LDAP, p.e. foo@foo.com" + +msgid "revert" +msgstr "revertir" + +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 se da soporte a \"cdrom\" y \"disk\"." + +msgid "Storage Pool" +msgstr "Agrupación de almacenamiento" + +msgid "Storage pool which volume located in" +msgstr "Agrupación de almacenamiento con volumen ubicado en" + +msgid "Storage Volume" +msgstr "Volumen de almacenamiento" + +msgid "Storage volume to be attached" +msgstr "Volumen de almacenamiento que se va a adjuntar" + +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 "Start" +msgstr "Iniciar" + +msgid "Reset" +msgstr "Restablecer" + +msgid "Pause" +msgstr "Poner en pausa" + +msgid "Resume" +msgstr "Reanudar" + +msgid "Power Off" +msgstr "Apagar" + +msgid "Actions" +msgstr "Acciones" + +msgid "Connect" +msgstr "Conectar" + +msgid "Clone" +msgstr "Clonar" + +msgid "Edit" +msgstr "Editar" + +msgid "Shut Down" +msgstr "Concluir" + +msgid "Delete" +msgstr "Suprimir" + +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 "No se puede leer el archivo. " + +msgid "Error while uploading file." +msgstr "Error al actualizar el archivo. " + +msgid "Delete Confirmation" +msgstr "Confirmación de supresión" + +msgid "OK" +msgstr "Aceptar" + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Warning" +msgstr "Aviso" + +msgid "Cloning..." +msgstr "Clonación..." + +msgid "Loading..." +msgstr "Cargando..." + +msgid "An error occurred while retrieving system information." +msgstr "Se ha producido un error al recuperar la información del sistema." + +msgid "Retry" +msgstr "Reintentar" + +msgid "Detailed message:" +msgstr "Mensaje detallado:" + +msgid "No ISO found" +msgstr "No se ha encontrado ningún ISO" + +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 "Esta operación puede necesitar mucho tiempo. ¿Desea continuar?" + +msgid "This will permanently delete the template. Would you like to continue?" +msgstr "Así se suprimirá la plantilla de forma permanente. ¿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 continuarpara 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 "Repositories" +msgstr "Repositorios" + +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 "Software Updates" +msgstr "Actualizaciones de software" + +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 "" +"No se ha podido recuperar la información de actualización de paquetes. " + +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 "Debug Reports" +msgstr "Informes de depuración" + +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 solamente letras, dígitos, el carácter de " +"subrayado ('_') y/o de guión ('-')." + +msgid "Pending..." +msgstr "Pendiente..." + +msgid "Report name is the same as the original one." +msgstr "El nombre de informe es el mismo que el original. " + +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 " +"se puede deshacer. ¿Desea continuar?" + +msgid "Power off Confirmation" +msgstr "Confirmación de apagado" + +msgid "" +"This action may produce undesirable results, for example unflushed disk " +"cache in the guest. Would you like to continue?" +msgstr "" +"Esta acción puede producir resultados no deseables, por ejemplo " +"almacenamiento de memoria caché en disco sin vaciar en el invitado. ¿Desea " +"continuar?" + +msgid "Reset Confirmation" +msgstr "Confirmación de restablecimiento" + +msgid "" +"There is a risk of data loss caused by reset without the guest OS shutdown. " +"Would you like to continue?" +msgstr "" +"Existe un riesgo de pérdida de datos causado por el restablecimiento sin la " +"conclusión del sistema operativo invitado. ¿Desea continuar?" + +msgid "Shut Down Confirmation" +msgstr "Confirmación de conclusión" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"Tenga en cuenta que el sistema operativo del invitado puede ignorar esta " +"solicitud. ¿Desea continuar?" + +msgid "Virtual Machine delete Confirmation" +msgstr "Confirmación de supresión de la máquina virtual " + +msgid "" +"This virtual machine is not persistent. Power Off will delete it. Continue?" +msgstr "" +"Esta máquina virtual no es persistente. Con la acción Apagar se suprimirá. " +"¿Desea 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 "" +"Cuando el invitado de destino tiene volúmenes SCSI o iSCSI, se clonarán en " +"la agrupación de almacenamiento predeterminada. Ocurrirá lo mismo cuando la " +"agrupación de destino no tenga espacio suficiente para clonar los volúmenes. " +"¿Desea continuar?" + +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 "" +"Este disco se desconectará de forma permanente y podrá volver a conectarlo. " +"¿Desea continuardesconectándolo?" + +msgid "interface:" +msgstr "interfaz: " + +msgid "address:" +msgstr "dirección:" + +msgid "link_type:" +msgstr "link_type:" + +msgid "block:" +msgstr "bloque:" + +msgid "drive_type:" +msgstr "drive_type:" + +msgid "model:" +msgstr "modelo:" + +msgid "Affected devices:" +msgstr "Dispositivos afectados:" + +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 red no es persistente. En lugar de detenerla, esta acción la suprimirá " +"de forma permanente. ¿Desea continuar?" + +msgid "" +"The bridged VLAN tag may not work well with NetworkManager enabled. You " +"should consider disabling it." +msgstr "" +"Es posible que el código VLAN ponteado no funcione bien si NetworkManager " +"está habilitado. Debería considerar la posibilidad de inhabilitarlo. " + +msgid "" +"This will permanently delete the storage pool. Would you like to continue?" +msgstr "" +"Así se suprimirá la agrupación de almacenamiento de forma permanente. ¿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 "Se están cargando los destinos iSCSI..." + +msgid "No iSCSI found. Please input one." +msgstr "No se ha encontrado el iSCSI. Indique uno. " + +msgid "Failed to load iSCSI targets." +msgstr "No se han podido cargar los destinos iSCSI. " + +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 "No es un nombre de servidor válido o IP válida. Modifique el valor. " + +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á de forma permanente. ¿Desea continuar?" + +msgid "Unable to retrieve partitions information." +msgstr "No se puede recuperar la información de particiones. " + +msgid "In progress..." +msgstr "En curso..." + +msgid "Failed!" +msgstr "Error" + +msgid "CDROM path needs to be a valid local/remote path and cannot be blank." +msgstr "" +"La vía de acceso de CDROM ha de ser una vía de acceso local/remota válida y " +"no puede dejarse en blanco. " + +msgid "Disk pool or volume cannot be blank." +msgstr "El volumen o la agrupación de discos no puede estar en blanco." + +msgid "Peers" +msgstr "Homólogos" + +msgid "Searching" +msgstr "Buscando" + +msgid "No peers found." +msgstr "No se han encontrado homólogos." + +msgid "Help" +msgstr "Ayuda" + +msgid "About" +msgstr "Acerca de" + +msgid "Log out" +msgstr "Finalizar sesión" + +msgid "Version:" +msgstr "Versión:" + +msgid "Session timeout, please re-login." +msgstr "" +"Se ha excedido el tiempo de espera de sesión; vuelva a iniciar la sesión." + +msgid "User Name" +msgstr "Nombre de usuario" + +msgid "Password" +msgstr "Contraseña" + +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 utilizado para identificar el informe. Si se omite, se elegirá un " +"nombre en base a la hora actual. El nombre puede contener: letras, dígitos, " +"carácter de subrayado (\"_\") y de guión (\"-\")." + +msgid "Rename a Debug Report" +msgstr "Renombre un informe de depuración" + +msgid "" +"The name used to identify the report. Name can contain: letters, digits and " +"hyphen (\"-\")." +msgstr "" +"El nombre utilizado para identificar el informe. El nombre puede contener: " +"letras, dígitos y el carácter de guión (\"-\")." + +msgid "Submit" +msgstr "Enviar" + +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 "Add a Volume to Storage Pool" +msgstr "Añadir un volumen a la agrupación de almacenamiento" + +msgid "Fetch from remote URL" +msgstr "Captar de URL remoto" + +msgid "Enter the remote URL here." +msgstr "Escriba el URL remoto aquí. " + +msgid "Upload a file" +msgstr "Cargar un archivo" + +msgid "Choose the file you want to upload." +msgstr "Elija el archivo que desee cargar. " + +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 "Device path" +msgstr "Vía de acceso del dispositivo" + +msgid "iSCSI Server" +msgstr "Servidor iSCSI" + +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 "Server" +msgstr "Servidor" + +msgid "Port" +msgstr "Puerto" + +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 "SCSI Adapter" +msgstr "Adaptador SCSI" + +msgid "Please, wait..." +msgstr "Por favor, espere..." + +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 "Archivo de imagen local" + +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 "File Path:" +msgstr "Vía de acceso del archivo:" + +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 "Processor" +msgstr "Procesador" + +msgid "CDROM" +msgstr "CDROM" + +msgid "Image File" +msgstr "Archivo de imagen" + +msgid "Graphics" +msgstr "Gráficos" + +msgid "Disk(GB)" +msgstr "Disco (GB)" + +msgid "Disk Format" +msgstr "Formato de disco" + +msgid "CPU Number" +msgstr "Número de CPU" + +msgid "Manually set CPU topology" +msgstr "Establezca manualmente la topología de CPU" + +msgid "Cores" +msgstr "Núcleos" + +msgid "Threads" +msgstr "Hebras" + +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 "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 "CPU(s)" +msgstr "CPU(s)" + +msgid "System Statistics" +msgstr "Estadísticas del sistema" + +msgid "Update Progress" +msgstr "Actualizar progreso" + +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 "El nombre no debe contener '/' y '\"'." + +msgid "Isolated: no external network connection" +msgstr "Aislado: no hay conexión de red externa" + +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 "(No se han encontrado interfaces) " + +msgid "Destination" +msgstr "Destino" + +msgid "Enable VLAN" +msgstr "Habilitar VLAN" + +msgid "VLAN ID" +msgstr "ID de VLAN" + +msgid "Stop" +msgstr "Detener" + +msgid "%Used" +msgstr "% Utilizado" + +msgid "Location" +msgstr "Ubicación" + +msgid "Capacity" +msgstr "Capacidad" + +msgid "Allocated" +msgstr "Asignado" + +msgid "active" +msgstr "activo" + +msgid "inactive" +msgstr "inactivo" + +msgid "Deactivate" +msgstr "Desactivar" + +msgid "Activate" +msgstr "Activar" + +msgid "Add Volume" +msgstr "Añadir volumen" + +msgid "Extend" +msgstr "Ampliar" + +msgid "Undefine" +msgstr "No definir" + +msgid "Format" +msgstr "Formato" + +msgid "Allocation" +msgstr "Asignación" + +msgid "No templates found." +msgstr "No se han encontrado plantillas." diff --git a/plugins/kimchi/po/fr_FR.po b/plugins/kimchi/po/fr_FR.po new file mode 100644 index 000000000..59c39b107 --- /dev/null +++ b/plugins/kimchi/po/fr_FR.po @@ -0,0 +1,2507 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: fr_FR\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" +"Plural-Forms: nplurals=2; plural=n>1;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Paramètre inconnu %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "La suppression n'est pas autorisée pour %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s n'implémente pas la méthode de mise à jour" + +#, python-format +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 d'analyser la demande JSON" + +msgid "This API only supports JSON" +msgstr "L'API prend uniquement en charge la notation JSON" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "Les paramètres ne correspondent pas aux exigences du schéma : %(err)s" + +msgid "You don't have permission to perform this operation." +msgstr "Vous ne disposez pas des droits pour 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 de modèle." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "Impossible de démarrer la tâche en raison de l'erreur : %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"Expiration du délai d'attente de %(seconds)s lors de l'exécution de la tâche " +"'%(task)s." + +#, python-format +msgid "Authentication failed for user '%(username)s'. [Error code: %(code)s]" +msgstr "" +"Echec d'authentification 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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Indiquez %(item)s pour la connexion à Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "" +"L'utilisateur %(user_id)s est introuvable avec les paramètres LDAP donnés." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Configuration LDAP non valide : %(item)s : %(value)s" + +msgid "Unknown \"_cap\" specified" +msgstr "\"_cap\" inconnu spécifié" + +msgid "\"_passthrough\" should be \"true\" or \"false\"" +msgstr "\"_passthrough\" doit avoir la valeur \"true\" ou \"false\"" + +msgid "\"_passthrough_affected_by\" should be a device name string" +msgstr "\"_passthrough_affected_by\" doit être une chaîne de nom d'unité" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\" doit avoir la valeur \"true\" ou \"false\"" + +#, python-format +msgid "Error while getting block devices. Details: %(err)s" +msgstr "Erreur lors de l'obtention d'unités par bloc. Détails : %(err)s" + +#, python-format +msgid "Error while getting block device information for %(device)s." +msgstr "" +"Erreur lors de l'obtention des informations d'unité par bloc pour %(device)s." + +#, python-format +msgid "Unable to find distro file: %(filename)s" +msgstr "Fichier de distribution introuvable : %(filename)s" + +#, python-format +msgid "" +"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file." +msgstr "" +"Impossible d'analyser le fichier de distribution : %(filename)s. Vérifiez " +"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 à la cible hôte 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 à la cible hôte %(host)s iSCSI %(target)s" + +#, python-format +msgid "Unable to find ISO file %(filename)s" +msgstr "Fichier ISO introuvable : %(filename)s" + +#, python-format +msgid "The ISO file %(filename)s is not bootable" +msgstr "Le fichier ISO %(filename)s n'est pas amorçable" + +#, python-format +msgid "The ISO file %(filename)s does not have a valid El Torito boot record" +msgstr "" +"Le fichier ISO %(filename)s ne possède pas d'enregistrement d'amorçage El " +"Torito valide" + +#, python-format +msgid "Invalid El Torito validation entry in ISO %(filename)s" +msgstr "" +"Entrée de validation El Torito non valide dans le fichier ISO %(filename)s" + +#, python-format +msgid "Invalid El Torito boot indicator in ISO %(filename)s" +msgstr "" +"Indicateur d'amorçage El Torito non valide dans le fichier ISO %(filename)s" + +#, python-format +msgid "Unexpected volume type for primary volume in ISO %(filename)s" +msgstr "" +"Type de volume inattendu pour le volume principal dans le fichier ISO " +"%(filename)s" + +#, python-format +msgid "Bad format while reading volume descriptor in ISO %(filename)s" +msgstr "" +"Format incorrect lors de la lecture du descripteur de volume dans le fichier " +"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 ne dispose pas des droits pour utiliser ce fichier ISO " +"%(filename)s. placez-le dans /var/lib/libvirt, ou définissez le droit de " +"recherche sur les listes de contrôle d'accès d'accès aux fichiers pour " +"l'utilisateur '%(user)s', si possible, ou ajoutez '%(user)s' au groupe de " +"chemins d'accès ISO ou (non recommandé) 'chmod -R o+x 'path_to_iso'." +"Détails : %(err)s" + +msgid "An error occurred when probing image OS information." +msgstr "" +"Une erreur s'est produite lors de l'application d'une sonde aux informations " +"de système d'exploitation d'image." + +msgid "No OS information found in given image." +msgstr "" +"Aucune information relative au système d'exploitation n'a été trouvée dans " +"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 entré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 nommée %(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éjà utilisé ou la machine virtuelle n'est pas hors tension." + +#, python-format +msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s" +msgstr "" +"Impossible d'extraire la capture d'écran pour la machine virtuelle arrêtée " +"%(name)s" + +msgid "Remote ISO image is not supported by this server." +msgstr "L'image ISO distante n'est pas prise en charge par ce serveur." + +#, python-format +msgid "Screenshot is not supported on virtual machine %(name)s" +msgstr "" +"La capture d'écran n'est pas prise en charge sur 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 hors tension %(name)s." + +msgid "Virtual machine name must be a string without slashes (/)" +msgstr "" +"Le nom de la machine virtuelle doit être une chaîne sans barre oblique (/)" + +#, python-format +msgid "Invalid template URI %(value)s specified for virtual machine" +msgstr "URI du modèle non valide %(value)s indiqué pour la machine virtuelle" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for virtual machine" +msgstr "" +"URI du pool de stockage non valide %(value)s indiqué pour la machine " +"virtuelle" + +msgid "Supported virtual machine graphics are Spice or VNC" +msgstr "Graphiques de machine virtuelle pris en charge : Spice ou VNC" + +msgid "Graphics address to listen on must be IPv4 or IPv6" +msgstr "L'adresse des graphiques pour l'écoute doit être IPv4 ou IPv6" + +msgid "Specify a template to create a virtual machine from" +msgstr "Indiquez un modèle pour créer une machine virtuelle depuis" + +#, 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éinitialiser la machine virtuelle %(name)s. Détails : %(err)s" + +msgid "User name list must be an array" +msgstr "La liste de noms d'utilisateur doit être un tableau" + +msgid "User name must be a string" +msgstr "Le nom d'utilisateur doit être une chaîne" + +msgid "Group name list must be an array" +msgstr "La liste de noms de groupe doit être un tableau" + +msgid "Group name must be a string" +msgstr "Le nom de groupe doit être une chaîne" + +#, python-format +msgid "User(s) '%(users)s' do not exist" +msgstr "Le ou les utilisateurs '%(users)s' n'existent pas" + +#, python-format +msgid "Group(s) '%(groups)s' do not exist" +msgstr "Le ou les groupes '%(groups)s' n'existent pas" + +#, python-format +msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s" +msgstr "Impossible d'arrêter la machine virtuelle %(name)s. Détails : %(err)s" + +msgid "The guest console password must be a string." +msgstr "Le mot de passe de la console invité doit être une chaîne." + +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é doit être une valeur " +"numérique." + +#, python-format +msgid "Virtual machine '%(name)s' must be stopped before cloning it." +msgstr "La machine virtuelle '%(name)s' doit être arrêtée avant d'être clonée." + +#, python-format +msgid "Insufficient disk space to clone virtual machine '%(name)s'" +msgstr "Espace disque insuffisant pour cloner la machine virtuelle '%(name)s'" + +#, python-format +msgid "Unable to clone VM '%(name)s'. Details: %(err)s" +msgstr "" +"Impossible de cloner la machine virtuelle '%(name)s'. Détails : %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "Opération non valide pour la machine virtuelle non permanente %(name)s" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "" +"Impossible d'interrompre la machine virtuelle '%(name)s' car elle n'est pas " +"en cours d'exécution." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "" +"Impossible d'interrompre la machine virtuelle '%(name)s'. Détails : %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "" +"Impossible de reprendre la machine virtuelle '%(name)s' car elle n'est pas " +"interrompue." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "" +"Impossible de reprendre la machine virtuelle '%(name)s'. Détails : %(err)s" + +msgid "Memory assigned is higher then the maximum allowed in the host." +msgstr "" +"La mémoire affectée est supérieure à la quantité maximale autorisée sur " +"l'hôte." + +#, python-format +msgid "" +"VM '%(name)s' does not support live memory update. Update the memory with " +"the machine offline to enable this feature." +msgstr "" +"La machine virtuelle '%(name)s' ne prend pas en charge la mise à jour " +"dynamique de la mémoire. Mettez à jour la mémoire avec la machine hors ligne " +"pour activer cette fonction." + +msgid "Only increase memory is allowed in active VMs" +msgstr "" +"Seule une augmentation de la mémoire est autorisée sur les machines " +"virtuelles actives" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"Pour la mise à jour dynamique de la mémoire, la nouvelle valeur de mémoire " +"doit être égale à l'ancienne valeur plus des multiples de 1024 Mib" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "" +"Il n'existe pas assez d'emplacements disponibles de 1024 Mib sur l'invité." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"La version libvirt de l'hôte ne prend pas en charge les unités de mémoire. " +"Libvirt doit être >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "Erreur d'attachement de l'unité de mémoire. Détails : %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "" +"Impossible de démarrer %(name)s. La machine virtuelle est déjà démarrée. " + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "" +"Impossible de mettre %(name)s hors tension. La machine virtuelle est " +"arrêtée. " + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "Impossible d'arrêter %(name)s. La machine virtuelle est arrêtée. " + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "" +"Impossible de réinitialiser %(name)s. La machine virtuelle est déjà arrêtée. " + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"La machine virtuelle VM %(vmid)s ne contient pas l'unité hôte affectée " +"directement %(dev_name)s." + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"L'unité hôte %(dev_name)s n'est pas autorisée à être affectée directement à " +"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 "" +"Aucun groupe IOMMU trouvé. Le passe-système PCI hôte a besoin d'un groupe " +"IOMMU pour fonctionner correctement. Activez Intel VT-d ou AMD IOMMU dans " +"votre BIOS, puis vérifiez que le noyau est compilé avec le support IOMMU. " +"Pour l'UC Intel, ajoutez intel_iommu=on pour le paramètre de noyau dans /" +"boot/grub2/grub.conf. Pour l'UC AMD, ajoutez iommu=pt iommu=1." + +msgid "\"name\" should be a device name string" +msgstr "\"name\" doit être une chaîne de nom d'unité" + +#, python-format +msgid "" +"The device %(name)s is probably in use by the host. Unable to attach it to " +"the guest." +msgstr "" +"L'unité %(name)s est probablement utilisée par l'hôte. Impossible de " +"l'attacher à l'hôte." + +#, python-format +msgid "Interface %(iface)s does not exist in virtual machine %(name)s" +msgstr "L'interface %(iface)s n'existe pas sur 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 indiqué pour la machine virtuelle %(name)s n'existe pas" + +msgid "Supported virtual machine interfaces type is only network" +msgstr "" +"Type d'interface de machine virtuelle pris en charge : 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" + +msgid "Invalid network model card specified for virtual machine interface" +msgstr "" +"La carte de modèle réseau spécifiée pour l'interface de la machine virtuelle " +"n'est pas valide" + +msgid "Specify type and network to add a new virtual machine interface" +msgstr "" +"Spécifiez un type et un réseau à ajouter à une nouvelle interface de machine " +"virtuelle" + +msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF" +msgstr "L'adresse MAC doit être conforme au format FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "L'adresse MAC %(mac)s existe déjà sur la machine virtuelle %(name)s" + +msgid "Invalid MAC Address" +msgstr "Adresse MAC non valide" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "" +"Impossible de modifier l'adresse MAC d'une machine virtuelle en cours " +"d'exécution" + +#, 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' indiqué 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 '%(pool)s' indiqué 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 '%(pool)s' indiqué pour le modèle %(template)s n'est pas " +"actif" + +#, python-format +msgid "Invalid parameter '%(param)s' specified for CDROM." +msgstr "Paramètre non valide '%(param)s' spécifié pour le CD-ROM." + +#, python-format +msgid "Network %(network)s specified for template %(template)s is not active" +msgstr "" +"Le réseau '%(network)s' indiqué pour le modèle %(template)s n'est pas actif" + +msgid "Template name must be a string" +msgstr "Le nom du modèle doit être une chaîne" + +msgid "Template icon must be a path to the image" +msgstr "L'icône de modèle doit être un chemin d'accès à l'image" + +msgid "Template distribution must be a string" +msgstr "La distribution du modèle doit être une chaîne" + +msgid "Template distribution version must be a string" +msgstr "La version de distribution du modèle doit être une chaîne" + +msgid "The number of CPUs must be an integer greater than 0" +msgstr "Le nombre d'UC doit être un 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 entier supérieur à 512" + +msgid "Template CDROM must be a local or remote ISO file" +msgstr "Le CD-ROM modèle doit être un fichier ISO local ou distant" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for template" +msgstr "URI du pool de stockage non valide %(value)s indiqué pour le modèle" + +msgid "Specify an ISO image as CDROM or a base image to create a template" +msgstr "" +"Indiquez une image ISO comme CD-ROM ou 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 du 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 "" +"Spécifiez un volume sur un modèle lorsque le pool de stockage est iSCSI ou " +"SCSI" + +#, 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 en raison de l'erreur suivante : %(err)s" + +#, python-format +msgid "Unable to delete template due error: %(err)s" +msgstr "" +"Impossible de supprimer le modèle en raison de l'erreur suivante : %(err)s" + +msgid "Disk size must be an integer greater than 1GB." +msgstr "La taille du disque doit être un entier supérieur à 1 Go." + +msgid "Template base image must be a valid local image file" +msgstr "L'image de base du modèle doit être un fichier image local valide" + +#, python-format +msgid "Cannot identify base image %(path)s format" +msgstr "Impossible d'identifier le format %(path)s de l'image de base" + +msgid "" +"When specifying CPU topology, VCPUs must be a product of sockets, cores, and " +"threads." +msgstr "" +"Lors de la spécification de la topologie d'UC, les UC virtuelles doivent " +"être un produit des sockets, coeurs et unités d'exécution." + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "" +"Lors de la spécification de la topologie d'UC, chaque élément doit être un " +"entier supérieur à zéro." + +msgid "" +"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, " +"qcow2, qed, raw, vmdk, vpc." +msgstr "" +"Format d'image de disque non valide. Formats valides : bochs, cloop, cow, " +"dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +#, 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écifiez %(item)s pour 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 répertorier les pools de stockage. Détails : %(err)s" + +#, python-format +msgid "Unable to create storage pool %(name)s. Details: %(err)s" +msgstr "Impossible 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 car le chemin d'exportation %(path)s risque " +"de bloquer lors du montage" + +#, python-format +msgid "Unable to create NFS Pool as export path %(path)s mount failed" +msgstr "" +"Impossible de créer le pool NFS car le montage du chemin d'exportation " +"%(path)s a échoué" + +#, python-format +msgid "Unsupported storage pool type: %(type)s" +msgstr "Type de pool de stockage non pris en charge : %(type)s" + +#, python-format +msgid "Error while retrieving storage pool XML to %(pool)s" +msgstr "Erreur d'extraction du fichier XML du pool de stockage dans %(pool)s" + +msgid "Storage pool name must be a string without slashes (/)" +msgstr "Le nom du pool de stockage doit être une chaîne sans barre oblique (/)" + +msgid "" +"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-" +"iso" +msgstr "" +"Types de pool de stockage pris en charge : 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" + +msgid "Storage pool host must be a IP or hostname" +msgstr "L'hôte du pool de stockage doit être une adresse IP ou un nom d'hôte" + +msgid "Storage pool device must be the absolute path to the block device" +msgstr "" +"L'unité du pool de stockage doit correspondre au chemin d'accès absolu à " +"l'unité par bloc" + +msgid "Storage pool devices parameter must be a list" +msgstr "" +"Le paramètre des unités du pool de stockage doivent constituer une liste" + +msgid "Target IQN of an iSCSI pool must be a string" +msgstr "Le nom qualifié iSCSI (IQN) cible d'un pool iSCSI doit être une chaîne" + +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 entier compris entre 1 " +"et 65535" + +msgid "iSCSI target username must be a string" +msgstr "Le nom d'utilisateur cible iSCSI doit être une chaîne" + +msgid "iSCSI target password must be a string" +msgstr "Le mot de passe cible iSCSI doit être une chaîne" + +msgid "Specify name and type to create a storage pool" +msgstr "Indiquez le nom et le 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 disque/une partition valide. Impossible de l'ajouter " +"au pool %(pool)s." + +#, python-format +msgid "Unable to extend logical pool %(pool)s. Details: %(err)s" +msgstr "Impossible d'étendre le pool logique %(pool)s. Détails : %(err)s" + +msgid "The parameter disks only can be updated for logical storage pool." +msgstr "" +"Les disques de paramètre peuvent être mis à jour uniquement pour le pool de " +"stockage logique." + +msgid "The SCSI host adapter name must be a string." +msgstr "Le nom de l'adaptateur hôte SCSI doit être une chaîne." + +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 est inaccessible." + +#, 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 est inaccessible." + +#, 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 car il est associé à plusieurs " +"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 car il est associé à plusieurs " +"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 volumes nommé '%(name)s' existe déjà. Choisissez 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 des informations " +"d'analyse approfondie en raison de l'erreur suivante : %(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écifiez %(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 répertorier 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 répertorier 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 d'effacer 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 prend pas en charge la création et la " +"suppression de volume" + +msgid "Storage volume name must be a string" +msgstr "Le nom du volume de stockage doit être une chaîne" + +msgid "Storage volume allocation must be an integer number" +msgstr "L'allocation de volume de stockage doit être un nombre entier" + +msgid "" +"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, " +"qcow, qcow2, qed, raw, vmdk, vpc." +msgstr "" +"Format du volume de stockage non pris en charge. Formats valides : bochs, " +"cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +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 des informations de " +"volume de stockage en raison de l'erreur suivante : %(err)s" + +#, python-format +msgid "Only one of parameter %(param)s can be specified" +msgstr "Un seul paramètre %(param)s peut être spécifié" + +#, python-format +msgid "Create volume from %(param)s is not supported" +msgstr "" +"La création d'un volume à partir de %(param)s n'est pas prise en charge" + +msgid "Storage volume capacity must be an integer number." +msgstr "" +"La capacité du volume de stockage doit correspondre à 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. Vérifiez ce dernier." + +#, python-format +msgid "" +"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: " +"%(err)s" +msgstr "" +"Impossible de cloner le volume de stockage '%(name)s' dans le pool " +"'%(pool)s'. Détails : %(err)s" + +msgid "Specify chunk data and its size to upload a file." +msgstr "" +"Spécifiez les données de bloc et leur taille pour télécharger un fichier." + +msgid "In order to upload a storage volume, specify the 'upload' parameter." +msgstr "" +"Pour télécharger un volume de stockage, spécifiez le paramètre 'upload'." + +msgid "" +"Unable to upload chunk data as it does not match with requested chunk size." +msgstr "" +"Impossible de télécharger les données de bloc car elles ne correspondent pas " +"à la taille de bloc." + +#, python-format +msgid "The storage volume %(vol)s is not under an upload process." +msgstr "" +"Le volume de stockage %(vol)s n'est pas soumis à un processus de " +"téléchargement." + +msgid "The upload chunk data will exceed the storage volume size." +msgstr "" +"Le téléchargement des données de bloc dépasse la taille du volume de " +"stockage." + +#, python-format +msgid "Unable to upload chunk data to storage volume. Details: %(err)s." +msgstr "" +"Impossible de télécharger les données de bloc dans le volume de stockage. " +"Détails : %(err)s." + +#, 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 indiqué pour le réseau %(network)s n'est pas " +"valide." + +#, python-format +msgid "Specify a network interface to create bridged network %(name)s" +msgstr "Indiquez une interface réseau pour créer le réseau routé %(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 indiqué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 contrôleur NIC nu, une unité de pontage ou de " +"liaison." + +#, 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 disponible 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 "" +"Le nom du réseau doit être une chaîne sans barre oblique (/) ni guillemet " +"(\")" + +msgid "Supported network types are isolated, NAT and bridge" +msgstr "Les types de réseau pris en charge sont isolé, NAT et routé" + +msgid "Network subnet must be a string with IP address and prefix or netmask" +msgstr "" +"Le sous-réseau du réseau doit être une chaîne avec adresse IP et préfixe ou " +"masque de réseau" + +msgid "Network interface must be a string" +msgstr "L'interface réseau doit être une chaîne" + +msgid "Network VLAN ID must be an integer between 1 and 4094" +msgstr "" +"L'ID réseau local virtuel du réseau doit être un entier compris entre 1 et " +"4094" + +msgid "Specify name and type to create a Network" +msgstr "Indiquez le nom et le 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 existe plusieurs machines " +"virtuelles %(vms)s et/ou 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 le réseau %(name)s. Il existe plusieurs machines " +"virtuelles %(vms)s et/ou modèles liés à ce réseau." + +#, python-format +msgid "Bridge device %(name)s can not be the trunk device of a VLAN." +msgstr "" +"L'unité de pontage %(name)s ne peut pas être l'unité de liaison d'un réseau " +"local virtuel." + +#, python-format +msgid "Failed to activate interface %(iface)s: %(err)s." +msgstr "Echec de 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 "" +"Echec de l'activation de l'interface %(iface)s. Vérifiez l'état de la " +"liaison physique." + +#, python-format +msgid "Failed to start network %(name)s. Details: %(err)s" +msgstr "Echec du démarrage du réseau %(name)s. Détails : %(err)s" + +#, python-format +msgid "Debug report %(name)s does not exist" +msgstr "Le rapport de débogage %(name)s n'existe pas" + +msgid "Debug report tool not found in system" +msgstr "Outil de génération de rapports de débogage introuvable sur 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ébogage %(name)s. Détails : %(err)s." + +#, python-format +msgid "Can not find any debug report with the given name %(name)s" +msgstr "Aucun rapport de débogage nommé %(name)s n'a été trouvé" + +#, python-format +msgid "Unable to generate debug report %(name)s. Details: %(err)s" +msgstr "" +"Impossible de générer le rapport de débogage %(name)s. Détails : %(err)s" + +msgid "You should give a name for the debug report file." +msgstr "Vous devez indiquer un nom pour le fichier du rapport de débogage." + +msgid "" +"Debug report name must be a string. Only letters, digits, underscore ('_') " +"and hyphen ('-') are allowed." +msgstr "" +"Le nom du rapport de débogage doit être une chaîne. Seuls des lettres, " +"chiffres, trait de soulignement ('_') et tiret ('-') sont autorisés." + +#, python-format +msgid "" +"The debug report with specified name \"%(name)s\" already exists. Please use " +"another one." +msgstr "" +"Le rapport de débogage nommé \"%(name)s\" existe déjà. Veuillez utiliser un " +"autre nom." + +#, python-format +msgid "Storage server %(server)s was not used by Kimchi" +msgstr "Le serveur de stockage %(server)s n'a pas été utilisé par Kimchi" + +#, python-format +msgid "Distro '%(name)s' does not exist" +msgstr "La distribution '%(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 l'hôte" + +msgid "Unable to shutdown host machine as there are running virtual machines" +msgstr "" +"Impossible d'arrêter la machine hôte car des machines virtuelles sont en " +"cours d'exécution" + +msgid "Unable to reboot host machine as there are running virtual machines" +msgstr "" +"Impossible de réamorcer la machine hôte car des machines virtuelles sont en " +"cours d'exécution" + +#, python-format +msgid "Node device '%(name)s' not found" +msgstr "Unité de noeud '%(name)s' introuvable" + +msgid "Conflicting flag filters specified." +msgstr "Filtres d'indicateur en conflit spécifiés." + +msgid "No packages marked for update" +msgstr "Aucun module marqué pour mise à jour" + +#, python-format +msgid "Package %(name)s is not marked to be updated." +msgstr "Le module %(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 lors de l'obtention des modules marqués pour mise à jour. Détails : " +"%(err)s" + +msgid "There is no compatible package manager for this system." +msgstr "Aucun gestionnaire de modules compatible pour ce système." + +#, python-format +msgid "Unable to find %(item)s in datastore" +msgstr "%(item)s introuvable dans le magasin de données" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "URI %(uri)s non valide" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" +"Dépassement de délai lors de l'exécution de la commande '%(cmd)s' après " +"%(seconds)s secondes" + +msgid "Unable to choose a virtual machine name" +msgstr "Impossible de sélectionner un nom de machine virtuelle" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Valeur de données '%(value)s' non valide" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Unité de données '%(unit)s' non valide" + +msgid "Invalid storage type. Types supported: 'cdrom', 'disk'" +msgstr "Type de stockage non valide. Types pris en charge : 'cdrom', 'disk'" + +#, python-format +msgid "The path '%(value)s' is not a valid local/remote path for the device" +msgstr "" +"Le chemin '%(value)s' n'est pas un chemin local/distant valide pour l'unité" + +msgid "Only CDROM path can be update." +msgstr "Seul le chemin du CD-ROM peut être mis à jour." + +#, python-format +msgid "" +"The storage device %(dev_name)s does not exist in the virtual machine " +"%(vm_name)s" +msgstr "" +"L'unité de stockage %(dev_name)s n'existe pas sur la machine virtuelle " +"%(vm_name)s" + +#, python-format +msgid "Error while creating new storage device: %(error)s" +msgstr "Erreur lors de la création de l'unité de stockage : %(error)s" + +#, python-format +msgid "Error while updating storage device: %(error)s" +msgstr "Erreur lors de la mise à jour de l'unité de stockage : %(error)s" + +#, python-format +msgid "Error while removing storage device: %(error)s" +msgstr "Erreur lors du retrait de l'unité de stockage : %(error)s" + +msgid "Do not support IDE device hot plug" +msgstr "Pas de prise en charge du remplacement à chaud d'unité IDE" + +msgid "" +"Specify type and path or type and pool/volume to add a new virtual machine " +"disk" +msgstr "" +"Spécifiez un type et un chemin pour ajouter un nouveau disque de machine " +"virtuelle" + +msgid "Specify path to update virtual machine disk" +msgstr "Indiquez le chemin pour mettre à jour le disque de machine virtuelle" + +#, python-format +msgid "Controller type %(type)s limitation of %(limit)s devices reached" +msgstr "Le type de contrôleur %(type)s a atteint sa limite de %(limit)s unités" + +#, python-format +msgid "Cannot retrieve disk path information for given pool/volume: %(error)s" +msgstr "" +"Impossible d'extraire les informations de chemin d'accès au disque pour le " +"pool/volume donné : %(error)s" + +msgid "Volume already in use by other virtual machine." +msgstr "Le volume est déjà utilisé par une autre machine virtuelle." + +msgid "" +"Only one of path or pool/volume can be specified to add a new virtual " +"machine disk" +msgstr "" +"Soit le chemin, soit le 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 choisi avec le format %(format)s n'est pas adapté au type de " +"stockage %(type)s" + +msgid "YUM Repository ID must be one word only string." +msgstr "L'ID référentiel YUM doit être une chaîne d'un seul mot." + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "L'URL du référentiel doit être de type http://, ftp:// ou file://." + +msgid "" +"Repository configuration is a dictionary with specific values according to " +"repository type." +msgstr "" +"La configuration de référentiel est un dictionnaire avec des valeurs " +"spécifiques en fonction du type de référentiel." + +msgid "Distribution to DEB repository must be a string" +msgstr "La distribution sur le référentiel DEB doit être une chaîne" + +msgid "Components to DEB repository must be listed in a array" +msgstr "" +"Les composants du référentiel DEB doivent être répertoriés dans un tableau" + +msgid "Components to DEB repository must be a string" +msgstr "Les composants du référentiel DEB doivent être une chaîne" + +msgid "Mirror list to repository must be a string" +msgstr "La liste miroir du référentiel doit être une chaîne" + +msgid "YUM Repository name must be string." +msgstr "Le nom de référentiel YUM doit être une chaîne." + +msgid "GPG check must be a boolean value." +msgstr "Le contrôle 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 sur le fichier ASCII." + +#, python-format +msgid "Could not update repository %(repo_id)s." +msgstr "Impossible de mettre à jour le référentiel %(repo_id)s." + +#, python-format +msgid "Repository %(repo_id)s does not exist." +msgstr "Le référentiel %(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 "" +"Indiquez l'URL de base du référentiel, la liste miroir ou le lien afin de " +"créer ou mettre à jour un référentiel YUM." + +msgid "Repository management tool was not recognized for your system." +msgstr "" +"L'outil de gestion de référentiel n'a pas été reconnu pour votre système." + +#, python-format +msgid "Repository %(repo_id)s is already enabled." +msgstr "Le référentiel %(repo_id)s est déjà activé." + +#, python-format +msgid "Repository %(repo_id)s is already disabled." +msgstr "Le référentiel %(repo_id)s est déjà désactivé." + +#, python-format +msgid "Could not remove repository %(repo_id)s." +msgstr "Impossible de supprimer le référentiel %(repo_id)s." + +#, python-format +msgid "Could not write repository configuration file %(repo_file)s" +msgstr "" +"Impossible d'écrire dans le fichier de configuration du référentiel " +"%(repo_file)s" + +msgid "Specify repository distribution in order to create a DEB repository." +msgstr "" +"Indiquez une distribution de référentiel pour créer un référentiel DEB." + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "Impossible d'activer le référentiel %(repo_id)s." + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "Impossible de désactiver le référentiel %(repo_id)s." + +msgid "YUM Repository ID already exists" +msgstr "L'ID référentiel YUM existe déjà" + +msgid "YUM Repository name must be a string" +msgstr "Le nom de référentiel YUM doit être une chaîne." + +#, python-format +msgid "Unable to list repositories. Details: '%(err)s'" +msgstr "Impossible de répertorier les référentiels. Détails : '%(err)s'" + +#, python-format +msgid "Unable to retrieve repository information. Details: '%(err)s'" +msgstr "" +"Impossible d'extraire les informations relatives au référentiel. Détails : " +"'%(err)s'" + +#, python-format +msgid "Unable to add repository. Details: '%(err)s'" +msgstr "Impossible d'ajouter le référentiel. Détails : '%(err)s'" + +#, python-format +msgid "Unable to remove repository. Details: '%(err)s'" +msgstr "Impossible de supprimer le référentiel. Détails : '%(err)s'" + +#, python-format +msgid "" +"Configuration items: '%(items)s' are not supported by repository manager" +msgstr "" +"Les éléments de configuration '%(items)s' ne sont pas pris en charge par le " +"gestionnaire de référentiel" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "Le lien du référentiel doit être une URL http://, ftp:// ou file://." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "Impossible de spécifier à la fois la liste miroir et le lien." + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "" +"La machine virtuelle '%(vm)s' doit être arrêtée avant la création d'une " +"image instantanée de celle-ci." + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossible de créer l'image instantanée '%(name)s' sur la machine virtuelle " +"'%(vm)s'. Détails : %(err)s" + +#, python-format +msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'." +msgstr "" +"L'image instantanée '%(name)s' n'existe pas sur la machine virtuelle " +"'%(vm)s'." + +#, python-format +msgid "" +"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossible d'extraire l'image instantanée '%(name)s' sur la machine " +"virtuelle '%(vm)s'. Détails : %(err)s" + +#, python-format +msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s" +msgstr "" +"Impossible de répertorier les images instantanées sur la machine virtuelle " +"'%(vm)s'. Détails : %(err)s" + +#, python-format +msgid "" +"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossible de supprimer l'image instantanée '%(name)s' sur la machine " +"virtuelle '%(vm)s'. Détails : %(err)s" + +#, python-format +msgid "" +"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossible d'extraire l'image instantanée en cours de la machine virtuelle " +"'%(vm)s'. Détails : %(err)s" + +#, python-format +msgid "" +"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: " +"%(err)s" +msgstr "" +"Impossible de rétablir la machine virtuelle '%(vm)s' à l'image instantanée " +"'%(name)s'. Détails : %(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 "" +"Impossible de créer l'image instantanée de la machine virtuelle '%(vm)s' car " +"elle contient un disque au format '%(format)s' ; seul 'qcow2' est pris en " +"charge." + +msgid "The number of vCPUs is too large for this system." +msgstr "Le nombre d'UC virtuelles est trop élevé pour ce système." + +msgid "Invalid vCPU/topology combination." +msgstr "Combinaison d'UC virtuelle/topologie non valide." + +msgid "This host (or current configuration) does not allow CPU topology." +msgstr "Cet hôte (ou configuration actuelle) n'autorise pas la topologie d'UC." + +msgid "ERROR CODE" +msgstr "CODE D'ERREUR" + +msgid "REASON" +msgstr "MOTIF" + +msgid "STACK" +msgstr "PILE" + +msgid "Go to Homepage" +msgstr "Accéder à la page d'accueil" + +msgid "Create a New Virtual Machine" +msgstr "Créer une machine virtuelle" + +msgid "Virtual Machine Name" +msgstr "Nom de la machine virtuelle" + +msgid "" +"The name used to identify the virtual machine. If omitted, a name will be " +"chosen based on the template used." +msgstr "" +"Nom utilisé pour identifier la machine virtuelle. S'il est omis, un nom sera " +"choisi en fonction du modèle utilisé." + +msgid "Template" +msgstr "Modèle" + +msgid "Please create a template first." +msgstr "Commencez par créer un modèle." + +msgid "Create a Template" +msgstr "Créer un modèle" + +msgid "Please choose a template." +msgstr "Sélectionnez un modèle." + +msgid "OS" +msgstr "SE" + +msgid "OS Version" +msgstr "Version SE" + +msgid "CPUS" +msgstr "Unités centrales" + +msgid "Memory" +msgstr "Mémoire" + +msgid "Create" +msgstr "Créer" + +msgid "Creating..." +msgstr "Création..." + +msgid "Edit Guest" +msgstr "Editer l'invité" + +msgid "General" +msgstr "Général" + +msgid "Storage" +msgstr "Stockage" + +msgid "Interface" +msgstr "Interface" + +msgid "Permission" +msgstr "Droits" + +msgid "Host PCI Device" +msgstr "Unité PCI hôte" + +msgid "Snapshot" +msgstr "Image instantanée" + +msgid "Name" +msgstr "Nom" + +msgid "CPUs" +msgstr "UC" + +msgid "Memory (MB)" +msgstr "Mémoire (Mo)" + +msgid "Icon" +msgstr "Icône" + +msgid "Device" +msgstr "Unité" + +msgid "Path" +msgstr "Chemin" + +msgid "Network" +msgstr "Réseau" + +msgid "Type" +msgstr "Type" + +msgid "MAC Address" +msgstr "Adresse MAC" + +msgid "Available system users and groups" +msgstr "Groupes et utilisateurs système disponibles" + +msgid "Users" +msgstr "Utilisateurs " + +msgid "Groups" +msgstr "Groupes" + +msgid "Selected system users and groups" +msgstr "Groupes et utilisateurs système sélectionnés" + +msgid "User" +msgstr "Utilisateur" + +msgid "All" +msgstr "Tout" + +msgid "To Add" +msgstr "A ajouter" + +msgid "Added" +msgstr "Ajouté" + +msgid "filter" +msgstr "filtre" + +msgid "Product" +msgstr "Produit" + +msgid "Vendor" +msgstr "Fournisseur" + +msgid "Created" +msgstr "Créé" + +msgid "Save" +msgstr "Sauvegarder" + +msgid "Replace" +msgstr "Remplacer" + +msgid "Detach" +msgstr "Détacher" + +msgid "Cancel" +msgstr "Annuler" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "ID utilisateur LDAP, par ex. foo@foo.com" + +msgid "revert" +msgstr "rétablir" + +msgid "Add a Storage Device to VM" +msgstr "Ajouter une unité de stockage à la machine virtuelle" + +msgid "Device Type" +msgstr "Type d'unité" + +msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported." +msgstr "" +"Type d'unité. Actuellement, \"cdrom\" et \"disk\" seulement sont pris en " +"charge." + +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 "Volume de stockage à attacher" + +msgid "File Path" +msgstr "Chemin d'accès au fichier" + +msgid "The ISO file path in the server for CDROM." +msgstr "Chemin d'accès au fichier ISO sur le serveur pour le CD-ROM." + +msgid "Attach" +msgstr "Attacher" + +msgid "Start" +msgstr "Démarrer" + +msgid "Reset" +msgstr "Réinitialiser" + +msgid "Pause" +msgstr "Pause" + +msgid "Resume" +msgstr "Reprendre" + +msgid "Power Off" +msgstr "Mettre hors tension" + +msgid "Actions" +msgstr "Actions" + +msgid "Connect" +msgstr "Se connecter" + +msgid "Clone" +msgstr "Cloner" + +msgid "Edit" +msgstr "Editer" + +msgid "Shut Down" +msgstr "Arrêter" + +msgid "Delete" +msgstr "Supprimer" + +msgid "The username or password you entered is incorrect. Please try again." +msgstr "" +"Le nom d'utilisateur ou le mot de passe entré est incorrect. Veuillez " +"recommencer." + +msgid "This field is required." +msgstr "Cette zone est obligatoire." + +msgid "Log in" +msgstr "Connexion" + +msgid "Logging in..." +msgstr "Connexion en cours..." + +msgid "Host" +msgstr "Hôte" + +msgid "Guests" +msgstr "Invités" + +msgid "Templates" +msgstr "Modèles" + +msgid "Failed to get application configuration" +msgstr "Echec d'obtention de la configuration d'application" + +msgid "This is not a valid Linux path" +msgstr "Ce chemin Linux n'est pas valide" + +msgid "This is not a valid URL." +msgstr "Cette URL n'est pas valide." + +msgid "No such data available." +msgstr "Aucune donnée de ce type disponible." + +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 "" +"Impossible de contacter le système hôte. Vérifiez que celui-ci est démarré " +"et que vous disposez d'une connectivité au système hôte. Réponse à la " +"demande HTTP %1. " + +msgid "Unable to read file." +msgstr "Impossible de lire le fichier." + +msgid "Error while uploading file." +msgstr "Erreur lors du téléchargement du fichier." + +msgid "Delete Confirmation" +msgstr "Confirmation de suppression" + +msgid "OK" +msgstr "OK" + +msgid "Confirm" +msgstr "Confirmer" + +msgid "Warning" +msgstr "Avertissement" + +msgid "Cloning..." +msgstr "Clonage en cours..." + +msgid "Loading..." +msgstr "Chargement en cours..." + +msgid "An error occurred while retrieving system information." +msgstr "" +"Une erreur s'est produite lors de l'extraction des informations système." + +msgid "Retry" +msgstr "Nouvelle tentative" + +msgid "Detailed message:" +msgstr "Message détaillé :" + +msgid "No ISO found" +msgstr "ISO introuvable" + +msgid "This is not a valid ISO file." +msgstr "Ceci n'est pas un fichier ISO valide." + +msgid "This may take a long time. Do you want to continue?" +msgstr "Cette opération peut être assez longue. Voulez-vous continuer ?" + +msgid "This will permanently delete the template. Would you like to continue?" +msgstr "Le modèle va être supprimé définitivement. Voulez-vous continuer ?" + +msgid "Unable to shut down system as there are some virtual machines running!" +msgstr "" +"Impossible d'arrêter le système car certaines machines virtuelles sont en " +"cours d'exécution !" + +msgid "Max:" +msgstr "Maximum :" + +msgid "Utilization" +msgstr "Utilisation" + +msgid "Available" +msgstr "Disponible" + +msgid "Read Rate" +msgstr "Vitesse de lecture" + +msgid "Write Rate" +msgstr "Vitesse d'é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 "" +"L'arrêt ou le redémarrage de l'hôte va entraîner la perte du travail non " +"sauvegardé. Poursuivre l'arrêt/le redémarrage ?" + +msgid "" +"Repository will be removed permanently and can't be recovered. Do you want " +"to continue?" +msgstr "" +"Le référentiel va être retiré définitivement et ne pourra pas être récupéré. " +"Voulez-vous continuer ?" + +msgid "Repositories" +msgstr "Référentiels" + +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 "Contrôle 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 "Software Updates" +msgstr "Mises à jour logicielles" + +msgid "Package Name" +msgstr "Nom du module" + +msgid "Version" +msgstr "Version" + +msgid "Architecture" +msgstr "Architecture" + +msgid "Repository" +msgstr "Référentiel" + +msgid "Update All" +msgstr "Tout mettre à jour" + +msgid "Updating..." +msgstr "Mise à jour en cours..." + +msgid "Failed to retrieve packages update information." +msgstr "Echec de l'extraction des informations de mise à jour des modules." + +msgid "Failed to update package(s)." +msgstr "Echec de mise à jour du ou des modules." + +msgid "" +"Debug report will be removed permanently and can't be recovered. Do you want " +"to continue?" +msgstr "" +"Le rapport de débogage va être retiré définitivement et ne pourra pas être " +"récupéré. Voulez-vous continuer ?" + +msgid "Debug Reports" +msgstr "Rapports de débogage" + +msgid "Generated Time" +msgstr "Heure génération" + +msgid "Generate" +msgstr "Générer" + +msgid "Generating..." +msgstr "Génération en cours..." + +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 du rapport doit comporter uniquement des lettres, chiffres, trait de " +"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 identique au nom d'origine." + +msgid "" +"This will delete the virtual machine and its virtual disks. This operation " +"cannot be undone. Would you like to continue?" +msgstr "" +"Cette opération va supprimer la machine virtuelle et ses disques virtuels. " +"L'opération ne peut pas être annulée. 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 peut produire des résultats indésirables, par exemple, un cache " +"de disque non vidé sur le système 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 "" +"Risque de perte de données suite à une réinitialisation sans arrêt du " +"système d'exploitation invité. Voulez-vous continuer ?" + +msgid "Shut Down Confirmation" +msgstr "Confirmation d'arrêt" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"Notez que le système d'exploitation invité peut ignorer cette demande. " +"Voulez-vous continuer ?" + +msgid "Virtual Machine delete Confirmation" +msgstr "Confirmation de la suppression de la machine virtuelle" + +msgid "" +"This virtual machine is not persistent. Power Off will delete it. Continue?" +msgstr "" +"Cette machine virtuelle n'est pas permanente. Elle sera supprimée lors de la " +"mise hors tension. Continuer ?" + +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 "" +"Lorsque l'invité cible comporte des volumes SCSI ou iSCSI, ces derniers sont " +"clonés dans le pool de stockage par défaut. Cela se produit également " +"lorsque le pool cible ne comporte pas suffisamment d'espace pour cloner les " +"volumes. Voulez-vous continuer ?" + +msgid "" +"This CDROM will be detached permanently and you can re-attach it. Continue " +"to detach it?" +msgstr "" +"Ce CD-ROM va être détaché définitivement et ne pourra pas être attaché à " +"nouveau. Continuer le détachement ?" + +msgid "Attaching..." +msgstr "Attachement en cours..." + +msgid "Replacing..." +msgstr "Remplacement en cours..." + +msgid "Successfully attached!" +msgstr "L'attachement a abouti." + +msgid "Successfully replaced!" +msgstr "Le remplacement a abouti." + +msgid "Successfully detached!" +msgstr "Le détachement a abouti." + +msgid "" +"This disk will be detached permanently and you can re-attach it. Continue to " +"detach it?" +msgstr "" +"Ce disque va être détaché définitivement et ne pourra pas être attaché à " +"nouveau. Continuer le détachement ?" + +msgid "interface:" +msgstr "interface :" + +msgid "address:" +msgstr "adresse :" + +msgid "link_type:" +msgstr "type_lien :" + +msgid "block:" +msgstr "bloc :" + +msgid "drive_type:" +msgstr "type_lecteur :" + +msgid "model:" +msgstr "modèle :" + +msgid "Affected devices:" +msgstr "Unités concernées :" + +msgid "The VLAN id must be between 1 and 4094." +msgstr "L'ID réseau local virtuel doit être compris 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 toute machine " +"virtuelle dépendant 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 "" +"Il ne s'agit pas d'un réseau permanent. Au lieu de l'arrêter, cette action " +"va le supprimer 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 "" +"Il se peut que l'étiquette Réseau local virtuel local routé ne fonctionne " +"pas correctement lorsque NetworkManager est activé. Vous devez envisager de " +"désactiver ce dernier." + +msgid "" +"This will permanently delete the storage pool. Would you like to continue?" +msgstr "" +"Le pool de stockage va être supprimé définitivement. 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 "" +"Le disque va être formaté et vous perdrez toutes les données qu'il contient. " +"Voulez-vous vraiment continuer ? " + +msgid "SCSI Fibre Channel" +msgstr "Fibre Channel SCSI" + +msgid "No SCSI adapters found." +msgstr "Aucun adaptateur SCSI trouvé." + +msgid "Loading iSCSI targets..." +msgstr "Chargement des cibles iSCSI..." + +msgid "No iSCSI found. Please input one." +msgstr "iSCSI introuvable. Spécifiez-le." + +msgid "Failed to load iSCSI targets." +msgstr "Echec du chargement des cibles iSCSI." + +msgid "The storage pool name can not be blank." +msgstr "Le nom du pool de stockage ne peut pas être vide." + +msgid "The storage pool path can not be blank." +msgstr "Le chemin du pool de stockage ne peut pas être vide." + +msgid "NFS server mount path can not be blank." +msgstr "Le chemin de montage du serveur NFS ne peut pas être vide." + +msgid "Invalid NFS mount path." +msgstr "Chemin de montage NFS non valide." + +msgid "No logical device selected." +msgstr "Aucune unité logique sélectionnée." + +msgid "The iSCSI target can not be blank." +msgstr "La cible iSCSI ne peut pas être vide." + +msgid "Server name can not be blank." +msgstr "Le nom du serveur ne peut pas être vide." + +msgid "This is not a valid Server Name or IP. Please, modify it." +msgstr "" +"Il ne s'agit pas d'un nom de serveur ou d'une adresse IP valide. Modifiez " +"cet élément." + +msgid "Looking for available partitions ..." +msgstr "Recherche des 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 "" +"Il ne s'agit pas d'un pool de stockage permanent. 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 d'extraire les informations relatives aux partitions." + +msgid "In progress..." +msgstr "En cours..." + +msgid "Failed!" +msgstr "Echec !" + +msgid "CDROM path needs to be a valid local/remote path and cannot be blank." +msgstr "" +"Le chemin de CD-ROM doit être un chemin local/distant et ne peut pas être à " +"blanc." + +msgid "Disk pool or volume cannot be blank." +msgstr "Le pool de stockage sur disque ou le volume ne peut pas être à blanc." + +msgid "Peers" +msgstr "Homologues" + +msgid "Searching" +msgstr "Recherche" + +msgid "No peers found." +msgstr "Homologue introuvable." + +msgid "Help" +msgstr "Aide" + +msgid "About" +msgstr "A propos de" + +msgid "Log out" +msgstr "Déconnexion" + +msgid "Version:" +msgstr "Version :" + +msgid "Session timeout, please re-login." +msgstr "Délai d'attente de session dépassé, veuillez vous reconnecter." + +msgid "User Name" +msgstr "Nom d'utilisateur" + +msgid "Password" +msgstr "Mot de passe" + +msgid "Generate a New Debug Report" +msgstr "Générer un nouveau rapport de débogage" + +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 "" +"Nom utilisé pour identifier le rapport. S'il est omis, un nom sera choisi en " +"fonction de l'heure en cours. Le nom peut contenir : des lettres, chiffres, " +"des traits de soulignement (\"_\") et des tirets (\"-\")." + +msgid "Rename a Debug Report" +msgstr "Renommer un rapport de débogage" + +msgid "" +"The name used to identify the report. Name can contain: letters, digits and " +"hyphen (\"-\")." +msgstr "" +"Nom utilisé pour identifier le rapport. Il peut contenir : des lettres, " +"chiffres et tiret (\"-\")." + +msgid "Submit" +msgstr "Soumettre" + +msgid "Add a Repository" +msgstr "Ajouter un référentiel" + +msgid "Identifier" +msgstr "Identificateur" + +msgid "Single word, unique identifier for the repository." +msgstr "Mot unique, identificateur unique pour le référentiel." + +msgid "Textual name for the repository." +msgstr "Nom textuel pour le référentiel." + +msgid "URL" +msgstr "URL" + +msgid "Required Field" +msgstr "Zone obligatoire" + +msgid "URL to the repository. Supported protocols are http, ftp, and file." +msgstr "" +"Adresse URL pour le référentiel. Les protocoles pris en charge sont http, " +"ftp, et file." + +msgid "Repository is a mirror" +msgstr "Le référentiel est un miroir" + +msgid "Distribution" +msgstr "Distribution" + +msgid "Distribution of the DEB repository." +msgstr "Distribution du référentiel DEB." + +msgid "Components" +msgstr "Composants" + +msgid "List of components in DEB repository." +msgstr "Liste des composants dans le référentiel DEB." + +msgid "Edit Repository" +msgstr "Editer le référentiel" + +msgid "Mirror List URL" +msgstr "URL liste miroir" + +msgid "Yes" +msgstr "Oui" + +msgid "No" +msgstr "Non" + +msgid "Add a Volume to Storage Pool" +msgstr "Ajouter un volume au pool de stockage" + +msgid "Fetch from remote URL" +msgstr "Extraire de l'URL distante" + +msgid "Enter the remote URL here." +msgstr "Indiquez ici l'URL distante." + +msgid "Upload a file" +msgstr "Télécharger un fichier" + +msgid "Choose the file you want to upload." +msgstr "Sélectionnez le fichier à télécharger." + +msgid "Define a New Storage Pool" +msgstr "Définir un nouveau pool de stockage" + +msgid "Storage Pool Name" +msgstr "Nom du pool de stockage" + +msgid "" +"The name used to identify the storage pools, and it should not be empty." +msgstr "" +"Nom utilisé pour identifier les pools de stockage. 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 "" +"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 tenter de créer le répertoire s'il n'en existe pas déjà un sur " +"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 ou nom d'hôte du serveur NFS. Peut être entré ou sélectionné depuis " +"l'historique." + +msgid "NFS Path" +msgstr "Chemin NFS" + +msgid "The NFS exported path on NFS server." +msgstr "Chemin NFS exporté ou serveur NFS." + +msgid "Device path" +msgstr "Chemin d'unité" + +msgid "iSCSI Server" +msgstr "Serveur iSCSI" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "IP ou nom d'hôte du serveur iSCSI. Ne doit pas être vide." + +msgid "Server" +msgstr "Serveur" + +msgid "Port" +msgstr "Port" + +msgid "Target" +msgstr "Cible" + +msgid "The iSCSI target on iSCSI server" +msgstr "Cible iSCSI sur le serveur iSCSI" + +msgid "Add iSCSI Authentication" +msgstr "Ajouter l'authentification iSCSI" + +msgid "iSCSI Authentication" +msgstr "Authentification iSCSI" + +msgid "SCSI Adapter" +msgstr "Adaptateur SCSI" + +msgid "Please, wait..." +msgstr "Veuillez patienter..." + +msgid "Add Template" +msgstr "Ajouter un modèle" + +msgid "Where is the source media for this template? " +msgstr "Où se trouve le support source pour ce 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 "Recherche d'ISO" + +msgid "The following ISOs are available:" +msgstr "Les images ISO suivantes sont disponibles :" + +msgid "OS: " +msgstr "SE : " + +msgid "Version: " +msgstr "Version : " + +msgid "Size: " +msgstr "Taille : " + +msgid "Search more ISOs" +msgstr "Rechercher d'autres images ISO" + +msgid "Create Templates from Selected ISO" +msgstr "Créer des modèles à partir de l'image ISO sélectionnée" + +msgid "I want to use a specific ISO file" +msgstr "Je souhaite utiliser un fichier ISO spécifique" + +msgid "File Path:" +msgstr "Chemin d'accès au fichier : " + +msgid "Loading default remote ISOs ..." +msgstr "Chargement d'ISO distants par défaut..." + +msgid "Arch: " +msgstr "Arch : " + +msgid "I want to use a custom URL" +msgstr "Je souhaite utiliser une URL personnalisée" + +msgid "Edit Template" +msgstr "Editer le modèle" + +msgid "Processor" +msgstr "Processeur" + +msgid "CDROM" +msgstr "CD-ROM" + +msgid "Image File" +msgstr "Fichier image" + +msgid "Graphics" +msgstr "Graphiques" + +msgid "Disk(GB)" +msgstr "Disque (Go)" + +msgid "Disk Format" +msgstr "Format de disque" + +msgid "CPU Number" +msgstr "Nombre d'UC" + +msgid "Manually set CPU topology" +msgstr "Définir manuellement la topologie d'UC" + +msgid "Cores" +msgstr "Coeurs" + +msgid "Threads" +msgstr "Unités d'exécution" + +msgid "CPU" +msgstr "UC" + +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 "Shut down" +msgstr "Arrêter" + +msgid "Restart" +msgstr "Redémarrer" + +msgid "Basic Information" +msgstr "Informations de base" + +msgid "OS Distro" +msgstr "SE distribution" + +msgid "OS Code Name" +msgstr "Nom de code SE" + +msgid "CPU(s)" +msgstr "UC" + +msgid "System Statistics" +msgstr "Statistiques système" + +msgid "Update Progress" +msgstr "Progression de la mise à jour" + +msgid "Network Name" +msgstr "Nom du réseau" + +msgid "State" +msgstr "Etat" + +msgid "Network Type" +msgstr "Type de réseau" + +msgid "Address Space" +msgstr "Espace adresse" + +msgid "Name should not contain '/' and '\"'." +msgstr "Le nom ne doit pas contenir '/' et '\"'." + +msgid "Isolated: no external network connection" +msgstr "Isolé : aucune connexion réseau externe" + +msgid "NAT: outbound physical network connection only" +msgstr "NAT : connexion réseau physique sortante uniquement" + +msgid "Bridged: Virtual machines are connected to physical network directly" +msgstr "Routé : machines virtuelles directement connectées au réseau physique" + +msgid "(No interfaces found)" +msgstr "(Interface introuvable)" + +msgid "Destination" +msgstr "Destination" + +msgid "Enable VLAN" +msgstr "Activer le réseau local virtuel" + +msgid "VLAN ID" +msgstr "ID réseau local virtuel" + +msgid "Stop" +msgstr "Arrêter" + +msgid "%Used" +msgstr "%Util" + +msgid "Location" +msgstr "Emplacement" + +msgid "Capacity" +msgstr "Capacité" + +msgid "Allocated" +msgstr "Alloué" + +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 "Extension" + +msgid "Undefine" +msgstr "Annuler définition" + +msgid "Format" +msgstr "Format" + +msgid "Allocation" +msgstr "Allocation" + +msgid "No templates found." +msgstr "Aucun modèle trouvé." diff --git a/plugins/kimchi/po/gen-pot.in b/plugins/kimchi/po/gen-pot.in new file mode 100644 index 000000000..0e3cd10fd --- /dev/null +++ b/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/plugins/kimchi/po/it_IT.po b/plugins/kimchi/po/it_IT.po new file mode 100644 index 000000000..848bf407b --- /dev/null +++ b/plugins/kimchi/po/it_IT.po @@ -0,0 +1,2460 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: it_IT\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" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Parametro sconosciuto %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "Eliminazione non consentita per %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s non implementa il metodo di aggiornamento" + +#, python-format +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" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "I parametri non corrispondono ai requisiti nello schema: %(err)s" + +msgid "You don't have permission to perform this operation." +msgstr "Non si dispone dell'autorizzazione per eseguire questa operazione." + +msgid "Datastore is not initiated in the model object." +msgstr "Archivio dati non inizializzato nell'oggetto modello." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "Impossibile avviare l'attività a causa dell'errore: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"È stato raggiunto il timeout di %(seconds)s secondi durante l'esecuzione " +"dell'attività '%(task)s." + +#, python-format +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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Specificare %(item)s per accedere a Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "Utente %(user_id)s non trovato con le impostazioni LDAP fornite." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Configurazione LDAP non valida: %(item)s : %(value)s" + +msgid "Unknown \"_cap\" specified" +msgstr "Specificato \"_cap\" sconosciuto" + +msgid "\"_passthrough\" should be \"true\" or \"false\"" +msgstr "\"_passthrough\" deve essere \"true\" o \"false\"" + +msgid "\"_passthrough_affected_by\" should be a device name string" +msgstr "\"_passthrough_affected_by\" deve essere una stringa nome dispositivo" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\" deve essere \"true\" o \"false\"" + +#, 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 alla destinazione host iSCSI %(portal)s. 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 "Impossibile trovare il file ISO %(filename)s" + +#, 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 sugli elenchi di controllo di accesso file per l'utente '%(user)s' " +"se possibile, oppure aggiungere '%(user)s' al gruppo percorso ISO oppure " +"(non consigliato) 'chmod -R o+x 'path_to_iso'. Dettagli: %(err)s" + +msgid "An error occurred when probing image OS information." +msgstr "" +"Si è verificato un errore durante l'analisi delle informazioni SO immagine." + +msgid "No OS information found in given image." +msgstr "Nessuna informazione SO trovata nell'immagine fornita." + +#, python-format +msgid "Unable to read image file %(filename)s" +msgstr "Impossibile leggere il file immagine %(filename)s" + +#, python-format +msgid "" +"Image file must be an existing file on system. %(filename)s is not a valid " +"input." +msgstr "" +"Il file immagine deve essere un file esistente sul sistema. %(filename)s non " +"è un valido input." + +#, 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 "" +"Impossibile ridenominare la macchina virtuale %(name)s. Il nome %(new_name)s " +"è già in uso o la macchina virtuale non è spenta." + +#, 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 "" +"L'esecuzione di un'immagine non è supportata sulla macchina virtuale %(name)s" + +#, 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 aggiornare 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 "Impossibile connettere la macchina virtuale %(name)s." + +msgid "Virtual machine name must be a string without slashes (/)" +msgstr "" +"Il nome della macchina virtuale deve essere una stringa senza barre (/)" + +#, python-format +msgid "Invalid template URI %(value)s specified for virtual machine" +msgstr "URI modello non valido %(value)s specificato per la macchina virtuale" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for virtual machine" +msgstr "" +"URI pool di memoria non valido %(value)s specificato per la macchina virtuale" + +msgid "Supported virtual machine graphics are Spice or VNC" +msgstr "I grafici macchina virtuale supportati sono Spice o VNC" + +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 spegnere 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 reimpostare la macchina virtuale %(name)s. Dettagli: %(err)s" + +msgid "User name list must be an array" +msgstr "L'elenco di nomi utente deve essere un array" + +msgid "User name must be a string" +msgstr "Il nome utente deve essere una stringa" + +msgid "Group name list must be an array" +msgstr "L'elenco di nomi gruppo deve essere un array" + +msgid "Group name must be a string" +msgstr "Il nome gruppo deve essere una stringa" + +#, python-format +msgid "User(s) '%(users)s' do not exist" +msgstr "L'utente o gli utenti '%(users)s' non esistono" + +#, python-format +msgid "Group(s) '%(groups)s' do not exist" +msgstr "Il gruppo o i gruppi '%(groups)s' non esistono" + +#, python-format +msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s" +msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli: %(err)s" + +msgid "The guest console password must be a string." +msgstr "" +"La password della console della macchina guest deve essere una stringa." + +msgid "The life time for the guest console password must be a number." +msgstr "" +"La durata per la password della console della macchina guest deve essere un " +"numero." + +#, python-format +msgid "Virtual machine '%(name)s' must be stopped before cloning it." +msgstr "" +"La macchina virtuale '%(name)s' deve essere arrestata prima di poterla " +"clonare." + +#, python-format +msgid "Insufficient disk space to clone virtual machine '%(name)s'" +msgstr "" +"Spazio su disco insufficiente per clonare la macchina virtuale '%(name)s'" + +#, python-format +msgid "Unable to clone VM '%(name)s'. Details: %(err)s" +msgstr "Impossibile clonare la VM '%(name)s'. Dettagli: %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "" +"Operazione non valida per la macchina virtuale non persistente %(name)s" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "Impossibile sospendere la VM '%(name)s' perché non è in esecuzione." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "Impossibile sospendere la VM '%(name)s'. Dettagli: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "Impossibile riprendere la VM '%(name)s' perché non è in pausa." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "Impossibile riprendere la VM '%(name)s'. Dettagli: %(err)s" + +msgid "Memory assigned is higher then the maximum allowed in the host." +msgstr "La memoria assegnata è superiore al massimo consentito nell'host." + +#, python-format +msgid "" +"VM '%(name)s' does not support live memory update. Update the memory with " +"the machine offline to enable this feature." +msgstr "" +"La VM '%(name)s' non supporta l'aggiornamento della memoria live. Aggiornare " +"la memoria con la macchina fuori linea per abilitare questa funzione." + +msgid "Only increase memory is allowed in active VMs" +msgstr "Nelle VM attive è consentito solo aumentare la memoria." + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"Per l'aggiornamento della memoria live, il nuovo valore di memoria deve " +"essere uguale al vecchio più multipli di 1024 Mib" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "" +"Non sono presenti sufficienti slot liberi di 1024 Mib nella macchina guest." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"La versione libvirt dell'host non supporta dispositivi di memoria. Libvirt " +"deve essere >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "" +"Errore durante il collegamento del dispositivo di memoria. Dettagli: " +"%(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "" +"Impossibile avviare %(name)s. La macchina virtuale è già in esecuzione." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "Impossibile spegnere %(name)s. La macchina virtuale è spenta. " + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "Impossibile arrestare %(name)s. La macchina virtuale è spenta. " + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "Impossibile reimpostare %(name)s. La macchina virtuale è già spenta. " + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"La VM %(vmid)s non contiene un dispositivo host assegnato direttamente " +"%(dev_name)s." + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"Il dispositivo host %(dev_name)s non consente di assegnare direttamente al " +"VM." + +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 "" +"Non è stato trovato alcun gruppo IOMMU. Per funzionare correttamente il pass-" +"through PCI host ha bisogno del gruppo IOMMU. Abilitare Intel VT-d o AMD " +"IOMMU nel BIOS e verificare quindi che il Kernel sia compilato con il " +"supporto IOMMU. per la CPU Intel, aggiungere intel_iommu=on al parametro " +"Kernel in /boot/grub2/grub.conf. Per la CPU AMD, aggiungere iommu=pt iommu=1." + +msgid "\"name\" should be a device name string" +msgstr "\"name\" deve essere una stringa nome dispositivo" + +#, python-format +msgid "" +"The device %(name)s is probably in use by the host. Unable to attach it to " +"the guest." +msgstr "" +"Il dispositivo %(name)s è probabilmente utilizzato dall'host. Impossibile " +"collegarlo alla macchina guest." + +#, 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 "L'indirizzo MAC deve rispettare il formato FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "L'indirizzo MAC %(mac)s esiste già nella macchina virtuale %(name)s" + +msgid "Invalid MAC Address" +msgstr "Indirizzo MAC non valido" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "" +"Impossibile modificare l'indirizzo MAC di una macchina virtuale in esecuzione" + +#, 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 maggiore di 0" + +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 o un'immagine di base 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 "" +"Se il pool di memoria è iSCSI o SCSI specificare un volume per un modello" + +#, python-format +msgid "The volume %(volume)s is not in storage pool %(pool)s" +msgstr "Il volume %(volume)s non è nel pool di memoria %(pool)s" + +#, 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 "La dimensione del disco deve essere un numero intero maggiore di 1GB." + +msgid "Template base image must be a valid local image file" +msgstr "" +"L'immagine di base del modello deve essere un file immagine locale valido" + +#, python-format +msgid "Cannot identify base image %(path)s format" +msgstr "Impossibile identificare il formato %(path)s dell'immagine di base" + +msgid "" +"When specifying CPU topology, VCPUs must be a product of sockets, cores, and " +"threads." +msgstr "" +"Quando si specifica la topologia CPU, le VCPU devono essere composte da " +"socket, core e thread." + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "" +"Quando si specifica la topologia CPU, ogni elemento deve essere un numero " +"intero maggiore di zero." + +msgid "" +"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, " +"qcow2, qed, raw, vmdk, vpc." +msgstr "" +"Formato immagine disco non valido. Formati validi: bochs, cloop, cow, dmg, " +"qcow, qcow2, qed, raw, vmdk, vpc." + +#, 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 "Errore durante il richiamo dell'XML del pool di memoria per %(pool)s" + +msgid "Storage pool name must be a string without slashes (/)" +msgstr "Il nome del pool di memoria deve essere una stringa senza barre (/)" + +msgid "" +"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-" +"iso" +msgstr "" +"I tipi di pool di memoria supportati sono dir, netfs, logico, iscsi, isci e " +"kimchi-iso" + +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 "" +"Il dispositivo pool di memoria deve essere il percorso assoluto al " +"dispositivo del blocco" + +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 "Il nome utente della destinazione iSCSI deve essere una stringa" + +msgid "iSCSI target password must be a string" +msgstr "La password della destinazione iSCSI deve essere una stringa" + +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 "Impossibile estendere il pool logico %(pool)s. Dettagli: %(err)s" + +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 "" +"Impossibile creare il volume di memoria %(volume)s perché il pool di memoria " +"%(pool)s non è attivo" + +#, 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 "" +"Formato del volume di memoria non supportato. Formati validi: bochs, cloop, " +"cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +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 "È possibile specificare solo un parametro %(param)s" + +#, python-format +msgid "Create volume from %(param)s is not supported" +msgstr "La creazione del volume da %(param)s non è supportata" + +msgid "Storage volume capacity must be an integer number." +msgstr "La capacità del volume di memoria deve essere un numero intero." + +msgid "Storage volume URL must be http://, https://, ftp:// or ftps://." +msgstr "" +"L'URL del volume di memoria deve essere http://, https://, ftp:// o ftps://." + +#, python-format +msgid "Unable to access file %(url)s. Please, check it." +msgstr "Impossibile accedere al file %(url)s. Verificare." + +#, python-format +msgid "" +"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile clonare il volume di memoria '%(name)s' nel pool '%(pool)s'. " +"Dettagli: %(err)s" + +msgid "Specify chunk data and its size to upload a file." +msgstr "Specificare dati sezione e dimensioni per caricare un file." + +msgid "In order to upload a storage volume, specify the 'upload' parameter." +msgstr "Per caricare un volume di memoria, specificare il parametro 'upload'." + +msgid "" +"Unable to upload chunk data as it does not match with requested chunk size." +msgstr "" +"Impossibile caricare i dati sezione perché non corrispondono con la " +"dimensione sezione richiesta." + +#, python-format +msgid "The storage volume %(vol)s is not under an upload process." +msgstr "" +"Il volume di memoria %(vol)s non è sottoposto a un processo di caricamento." + +msgid "The upload chunk data will exceed the storage volume size." +msgstr "" +"I dati sezione da caricare supereranno la dimensione del volume di memoria." + +#, python-format +msgid "Unable to upload chunk data to storage volume. Details: %(err)s." +msgstr "" +"Impossibile caricare i dati sezione nel volume di memoria. Dettagli: %(err)s." + +#, 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 "Interfaccia %(iface)s già esistente." + +msgid "Network name must be a string without slashes (/) or quotes (\")" +msgstr "" +"Il nome della rete deve essere una stringa senza barre (/) o virgolette (\")" + +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 virtuali " +"%(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 "Impossibile avviare la rete %(name)s. Dettagli: %(err)s" + +#, 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 "Impossibile trovare un report di debug con il nome fornito %(name)s" + +#, 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 "È necessario fornire un nome per il file report di debug." + +msgid "" +"Debug report name must be a string. Only letters, digits, underscore ('_') " +"and hyphen ('-') are allowed." +msgstr "" +"Il nome report di debug deve essere una stringa. Sono consentiti solo " +"lettere, cifre, sottolineature ('_') e trattini ('-')." + +#, python-format +msgid "" +"The debug report with specified name \"%(name)s\" already exists. Please use " +"another one." +msgstr "" +"Il report di debug con il nome specificato \"%(name)s\" già esiste. " +"Utilizzare un altro." + +#, 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 "Sono stati specificati dei filtri indicatore in conflitto." + +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 "Unable to find %(item)s in datastore" +msgstr "Impossibile trovare %(item)s nell'archivio dati" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "URI non valido %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" +"Timeout durante l'esecuzione del comando '%(cmd)s' dopo %(seconds)s secondi" + +msgid "Unable to choose a virtual machine name" +msgstr "Impossibile scegliere un nome di macchina virtuale" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Valore dati non valido '%(value)s'" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Unità dati non valida '%(unit)s'" + +msgid "Invalid storage type. Types supported: 'cdrom', 'disk'" +msgstr "Tipo di memoria non valido. Tipi supportati: 'cdrom', 'disk'" + +#, python-format +msgid "The path '%(value)s' is not a valid local/remote path for the device" +msgstr "" +"Il percorso '%(value)s' non è un percorso locale/remoto valido per il " +"dispositivo" + +msgid "Only CDROM path can be update." +msgstr "È possibile aggiornare solo il percorso CDROM." + +#, python-format +msgid "" +"The storage device %(dev_name)s does not exist in the virtual machine " +"%(vm_name)s" +msgstr "" +"Il dispositivo di memoria %(dev_name)s non esiste nella macchina virtuale " +"%(vm_name)s" + +#, 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 "Non supportare hot plug dispositivo IDE" + +msgid "" +"Specify type and path or type and pool/volume to add a new virtual machine " +"disk" +msgstr "" +"Specificare il tipo e il percorso oppure il tipo e il pool/volume per " +"aggiungere un nuovo disco di 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 "" +"Il tipo di controller %(type)s ha raggiunto il limite di %(limit)s " +"dispositivi" + +#, python-format +msgid "Cannot retrieve disk path information for given pool/volume: %(error)s" +msgstr "" +"Impossibile richiamare le informazioni del percorso disco per il pool/volume " +"fornito: %(error)s" + +msgid "Volume already in use by other virtual machine." +msgstr "Il volume è già utilizzato da un'altra macchina virtuale." + +msgid "" +"Only one of path or pool/volume can be specified to add a new virtual " +"machine disk" +msgstr "" +"È possibile specificare solo uno tra percorso o pool/volume per aggiungere " +"un nuovo disco di macchina virtuale" + +#, python-format +msgid "" +"Volume chosen with format %(format)s does not fit in the storage type " +"%(type)s" +msgstr "" +"Il volume scelto con il formato %(format)s non si adatta nel tipo di memoria " +"%(type)s" + +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 "" +"L'elenco di elementi speculari per il repository deve essere una stringa" + +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 "" +"Specificare l'URL di base del repository, l'elenco di elementi speculari o " +"metalink per poter creare o aggiornare un repository YUM." + +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 "" +"Elementi di configurazione: '%(items)s' non supportati dal gestore repository" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "Il metalink del repository deve essere http://, ftp:// o file:// URL." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "" +"Impossibile specificare contemporaneamente elenco di elementi speculari e " +"metalink." + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "" +"La macchina virtuale '%(vm)s' deve essere arrestata prima di poterne creare " +"l'istantanea." + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile creare l'istantanea '%(name)s' sulla macchina virtuale '%(vm)s'. " +"Dettagli: %(err)s" + +#, python-format +msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'." +msgstr "L'istantanea '%(name)s' non esiste sulla macchina virtuale '%(vm)s'." + +#, python-format +msgid "" +"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile richiamare l'istantanea '%(name)s' sulla macchina virtuale " +"'%(vm)s'. Dettagli: %(err)s" + +#, python-format +msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s" +msgstr "" +"Impossibile elencare le istantanee sulla macchina virtuale '%(vm)s'. " +"Dettagli: %(err)s" + +#, python-format +msgid "" +"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile eliminare l'istantanea '%(name)s' sulla macchina virtuale " +"'%(vm)s'. Dettagli: %(err)s" + +#, python-format +msgid "" +"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile richiamare l'istantanea corrente sulla macchina virtuale " +"'%(vm)s'. Dettagli: %(err)s" + +#, python-format +msgid "" +"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: " +"%(err)s" +msgstr "" +"Impossibile invertire la macchina virtuale '%(vm)s' alla istantanea " +"'%(name)s'. Dettagli: %(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 "" +"Impossibile creare l'istantanea della macchina virtuale '%(vm)s' perché " +"contiene un disco con formato '%(format)s'; solo 'qcow2' è supportato." + +msgid "The number of vCPUs is too large for this system." +msgstr "Il numero di vCPU è troppo grande per questo sistema." + +msgid "Invalid vCPU/topology combination." +msgstr "Combinazione vCPU/topologia non valida." + +msgid "This host (or current configuration) does not allow CPU topology." +msgstr "Questo host (o configurazione corrente) non consente la topologia CPU." + +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 "Creazione..." + +msgid "Edit Guest" +msgstr "Modifica macchina guest" + +msgid "General" +msgstr "Generale" + +msgid "Storage" +msgstr "Memoria" + +msgid "Interface" +msgstr "Interfaccia" + +msgid "Permission" +msgstr "Autorizzazione" + +msgid "Host PCI Device" +msgstr "Dispositivo PCI host" + +msgid "Snapshot" +msgstr "Istantanea" + +msgid "Name" +msgstr "Nome" + +msgid "CPUs" +msgstr "CPU" + +msgid "Memory (MB)" +msgstr "Memoria (MB)" + +msgid "Icon" +msgstr "Icona" + +msgid "Device" +msgstr "Dispositivo" + +msgid "Path" +msgstr "Percorso" + +msgid "Network" +msgstr "Rete" + +msgid "Type" +msgstr "Tipo" + +msgid "MAC Address" +msgstr "Indirizzo MAC" + +msgid "Available system users and groups" +msgstr "Utenti e gruppi di sistema disponibili" + +msgid "Users" +msgstr "Utenti" + +msgid "Groups" +msgstr "Gruppi" + +msgid "Selected system users and groups" +msgstr "Utenti e gruppi di sistema selezionati" + +msgid "User" +msgstr "Utente" + +msgid "All" +msgstr "Tutti" + +msgid "To Add" +msgstr "Da aggiungere" + +msgid "Added" +msgstr "Aggiunto" + +msgid "filter" +msgstr "filtro" + +msgid "Product" +msgstr "Prodotto" + +msgid "Vendor" +msgstr "Fornitore" + +msgid "Created" +msgstr "Creato" + +msgid "Save" +msgstr "Salva" + +msgid "Replace" +msgstr "Sostituisci" + +msgid "Detach" +msgstr "Scollega" + +msgid "Cancel" +msgstr "Annulla" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "ID utente LDAP, ad esempio foo@foo.com" + +msgid "revert" +msgstr "Inverti" + +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, sono supportati \"cdrom\" e \"disk\"." + +msgid "Storage Pool" +msgstr "Pool di memoria" + +msgid "Storage pool which volume located in" +msgstr "Pool di memoria in cui si trova il volume" + +msgid "Storage Volume" +msgstr "Volume di memoria" + +msgid "Storage volume to be attached" +msgstr "Volume di memoria oggetto del collegamento" + +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 "Start" +msgstr "Avvia" + +msgid "Reset" +msgstr "Reimposta" + +msgid "Pause" +msgstr "In pausa" + +msgid "Resume" +msgstr "Riprendi" + +msgid "Power Off" +msgstr "Spegni" + +msgid "Actions" +msgstr "Azioni" + +msgid "Connect" +msgstr "Connetti" + +msgid "Clone" +msgstr "Clona" + +msgid "Edit" +msgstr "Modifica" + +msgid "Shut Down" +msgstr "Arresta" + +msgid "Delete" +msgstr "Elimina" + +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 abbia la connettività di rete. Risposta alla richiesta HTTP %1. " + +msgid "Unable to read file." +msgstr "Impossibile leggere il file." + +msgid "Error while uploading file." +msgstr "Errore durante il caricamento del file." + +msgid "Delete Confirmation" +msgstr "Conferma eliminazione" + +msgid "OK" +msgstr "OK" + +msgid "Confirm" +msgstr "Conferma" + +msgid "Warning" +msgstr "Avvertenza" + +msgid "Cloning..." +msgstr "Clonazione..." + +msgid "Loading..." +msgstr "Caricamento in corso..." + +msgid "An error occurred while retrieving system information." +msgstr "" +"Si è verificato un errore durante il richiamo delle informazioni di sistema." + +msgid "Retry" +msgstr "Riprova" + +msgid "Detailed message:" +msgstr "Messaggio dettagliato:" + +msgid "No ISO found" +msgstr "Nessun file ISO trovato" + +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 "Questa operazione può richiedere del tempo. Si desidera continuare?" + +msgid "This will permanently delete the template. Would you like to continue?" +msgstr "L'azione eliminerà permanentemente il modello. Si desidera 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 "Repositories" +msgstr "Repository" + +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 "Software Updates" +msgstr "Aggiornamenti del software" + +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 "" +"Richiamo delle informazioni di aggiornamento dei pacchetti non riuscito." + +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 "Debug Reports" +msgstr "Report di debug" + +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, sottolineature ('_') e/" +"o trattini ('-')." + +msgid "Pending..." +msgstr "In sospeso..." + +msgid "Report name is the same as the original one." +msgstr "Il nome report è uguale a quello originale." + +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. Si desidera continuare?" + +msgid "Power off Confirmation" +msgstr "Conferma spegnimento" + +msgid "" +"This action may produce undesirable results, for example unflushed disk " +"cache in the guest. Would you like to continue?" +msgstr "" +"Questa azione può produrre dei risultati indesiderabili, ad esempio una " +"cache di disco non ripulita nella macchina guest. Si desidera continuare?" + +msgid "Reset Confirmation" +msgstr "Conferma reimpostazione" + +msgid "" +"There is a risk of data loss caused by reset without the guest OS shutdown. " +"Would you like to continue?" +msgstr "" +"C'è un rischio di perdita di dati causato dalla reimpostazione senza " +"l'arresto del sistema operativo della macchina guest. Si desidera continuare?" + +msgid "Shut Down Confirmation" +msgstr "Conferma dell'arresto" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"Notare che il sistema operativo della macchina guest può ignorare questa " +"richiesta. Si desidera continuare?" + +msgid "Virtual Machine delete Confirmation" +msgstr "Conferma di eliminazione della macchina virtuale" + +msgid "" +"This virtual machine is not persistent. Power Off will delete it. Continue?" +msgstr "" +"Questa macchina virtuale non è persistente. Lo spegnimento la eliminerà. " +"Continuare?" + +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 la macchina guest di destinazione ha volumi SCSI o iSCSI, essi " +"verranno clonati sul pool di memoria predefinito. Lo stesso accadrà se il " +"pool di destinazione non ha spazio sufficiente per clonare i volumi. Si " +"desidera continuare?" + +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 "" +"Il disco verrà scollegato permanentemente e sarà possibile ricollegarlo. " +"Continuare con lo scollegamento?" + +msgid "interface:" +msgstr "interfaccia:" + +msgid "address:" +msgstr "indirizzo:" + +msgid "link_type:" +msgstr "tipo_link:" + +msgid "block:" +msgstr "blocco:" + +msgid "drive_type:" +msgstr "tipo_drive:" + +msgid "model:" +msgstr "modello:" + +msgid "Affected devices:" +msgstr "Dispositivi influenzati:" + +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 "" +"Questa rete non è permanente. Invece di arrestarla, questa azione la " +"eliminerà permanentemente. Si desidera continuare?" + +msgid "" +"The bridged VLAN tag may not work well with NetworkManager enabled. You " +"should consider disabling it." +msgstr "" +"La tag VLAN con bridge potrebbe non funzionare bene con NetworkManager " +"abilitato. Si dovrebbe prendere in considerazione la sua disabilitazione." + +msgid "" +"This will permanently delete the storage pool. Would you like to continue?" +msgstr "" +"L'azione eliminerà permanentemente il pool di memoria. Si desidera " +"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 "Caricamento delle destinazioni iSCSI..." + +msgid "No iSCSI found. Please input one." +msgstr "iSCSI non trovato. Immetterne uno." + +msgid "Failed to load iSCSI targets." +msgstr "Impossibile caricare le destinazioni iSCSI." + +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 "Nome server o IP non validi. Modificarli." + +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. Si desidera continuare?" + +msgid "Unable to retrieve partitions information." +msgstr "Impossibile caricare le informazioni sulla partizione." + +msgid "In progress..." +msgstr "In corso..." + +msgid "Failed!" +msgstr "Non riuscito." + +msgid "CDROM path needs to be a valid local/remote path and cannot be blank." +msgstr "" +"Il percorso CDROM deve essere un percorso locale/remoto valido e non può " +"essere vuoto." + +msgid "Disk pool or volume cannot be blank." +msgstr "Il volume o il pool di dischi non può essere vuoto." + +msgid "Peers" +msgstr "Peer" + +msgid "Searching" +msgstr "Ricerca" + +msgid "No peers found." +msgstr "Nessun peer trovato." + +msgid "Help" +msgstr "Guida" + +msgid "About" +msgstr "Info su" + +msgid "Log out" +msgstr "Disconnetti" + +msgid "Version:" +msgstr "Versione:" + +msgid "Session timeout, please re-login." +msgstr "Timeout della sessione; rieseguire l'accesso." + +msgid "User Name" +msgstr "Nome utente" + +msgid "Password" +msgstr "Password" + +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 omesso, ne verrà scelto " +"uno in base all'ora corrente. Il nome può contenere lettere, cifre, " +"sottolineature (\"_\") e trattini (\"-\")." + +msgid "Rename a Debug Report" +msgstr "Ridenomina un 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. Il nome può contenere " +"lettere, cifre e trattini (\"-\")." + +msgid "Submit" +msgstr "Inoltra" + +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 "Add a Volume to Storage Pool" +msgstr "Aggiungi un volume al pool di memoria" + +msgid "Fetch from remote URL" +msgstr "Richiama da URL remoto" + +msgid "Enter the remote URL here." +msgstr "Immettere qui l'URL remoto." + +msgid "Upload a file" +msgstr "Carica un file" + +msgid "Choose the file you want to upload." +msgstr "Selezionare il file da caricare." + +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 "Device path" +msgstr "Percorso dispositivo" + +msgid "iSCSI Server" +msgstr "Server iSCSI" + +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 "Server" +msgstr "Server" + +msgid "Port" +msgstr "Porta" + +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 "SCSI Adapter" +msgstr "Adattatore SCSI" + +msgid "Please, wait..." +msgstr "Attendere..." + +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 "File immagine locale" + +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 "File Path:" +msgstr "Percorso file:" + +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 "Processor" +msgstr "Processore" + +msgid "CDROM" +msgstr "CDROM" + +msgid "Image File" +msgstr "File immagine" + +msgid "Graphics" +msgstr "Grafici" + +msgid "Disk(GB)" +msgstr "Disco (GB)" + +msgid "Disk Format" +msgstr "Formato disco" + +msgid "CPU Number" +msgstr "Numero CPU" + +msgid "Manually set CPU topology" +msgstr "Imposta manualmente la topologia CPU" + +msgid "Cores" +msgstr "Core" + +msgid "Threads" +msgstr "Thread" + +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 "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 "CPU(s)" +msgstr "CPU" + +msgid "System Statistics" +msgstr "Statistiche di sistema" + +msgid "Update Progress" +msgstr "Avanzamento aggiornamento" + +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 "Il nome non deve contenere '/' e '\"'." + +msgid "Isolated: no external network connection" +msgstr "Isolata: nessuna connessione di rete esterna" + +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 "(Nessuna interfaccia trovata)" + +msgid "Destination" +msgstr "Destinazione" + +msgid "Enable VLAN" +msgstr "Abilita VLAN" + +msgid "VLAN ID" +msgstr "ID VLAN" + +msgid "Stop" +msgstr "Arresta" + +msgid "%Used" +msgstr "% utilizzata" + +msgid "Location" +msgstr "Ubicazione" + +msgid "Capacity" +msgstr "Capacità" + +msgid "Allocated" +msgstr "Assegnato" + +msgid "active" +msgstr "attivo" + +msgid "inactive" +msgstr "non attivo" + +msgid "Deactivate" +msgstr "Disattiva" + +msgid "Activate" +msgstr "Attiva" + +msgid "Add Volume" +msgstr "Aggiungi volume" + +msgid "Extend" +msgstr "Estendi" + +msgid "Undefine" +msgstr "Rimuovi definizione" + +msgid "Format" +msgstr "Formato" + +msgid "Allocation" +msgstr "Assegnazione" + +msgid "No templates found." +msgstr "Nessun modello trovato." diff --git a/plugins/kimchi/po/ja_JP.po b/plugins/kimchi/po/ja_JP.po new file mode 100644 index 000000000..b86974cbf --- /dev/null +++ b/plugins/kimchi/po/ja_JP.po @@ -0,0 +1,2441 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: ja_JP\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" +"Plural-Forms: nplurals=1; plural=0;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "パラメーター %(value)s が不明です" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "%(resource)s に対して削除は許可されません" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s は更新メソッドを実装していません" + +#, python-format +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 のみサポートします" + +#, python-format +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 "データ・ストアは、モデル・オブジェクトで開始されていません。" + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "次のエラーのため、タスクを開始できません: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"タスク %(task)s の実行中に %(seconds)s 秒のタイムアウトが満了しました。" + +#, python-format +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 へのアクセスを許可されていません" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Kimchi にログインするには、%(item)s を指定します" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "指定の LDAP 設定を持つユーザー %(user_id)s が見つかりません。" + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "LDAP 構成が無効です: %(item)s : %(value)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」はデバイス名ストリングでなければなりません" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "「_available_only」は「true」または「false」でなければなりません" + +#, 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 "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 内の 1 次ボリュームが予期しないボリューム・タイプです" + +#, 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 "イメージ OS 情報のプローブ時にエラーが発生しました。" + +msgid "No OS information found in given image." +msgstr "OS 情報が指定のイメージに見つかりません。" + +#, 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 "" +"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" + +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 "VM「%(name)s」のクローンを作成できません。詳細: %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "非永続仮想マシン %(name)s の操作が無効です" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "VM「%(name)s」は実行されていないため、中断できません。" + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "VM「%(name)s」を中断できません。詳細: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "VM「%(name)s」は一時停止されていないため、再開できません。" + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "VM「%(name)s」を再開できません。詳細: %(err)s" + +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 "" +"VM「%(name)s」ではライブ・メモリー・アップデートはサポートされていません。オ" +"フライン状態のマシンでメモリーを更新して、この機能を使用可能にしてください。" + +msgid "Only increase memory is allowed in active VMs" +msgstr "アクティブ VM ではメモリーの増加のみが許可されています" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"ライブ・メモリー・アップデートの場合、新規メモリー値は、旧メモリー値に1024 " +"Mib の倍数を加算した値に等しくなければなりません" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "1024 Mib のフリー・スロットがゲストで不足しています。" + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"ホストの libvirt バージョンではメモリー・デバイスはサポートされていません。" +"Libvirt は 1.2.14 以上でなければなりません" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "メモリー・デバイスの接続エラーです。詳細: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "%(name)s を開始できません。仮想マシンは既に稼働中です。" + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "" +"%(name)s の電源をオフにできません。仮想マシンはシャットオフされています。" + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "" +"%(name)s をシャットダウンできません。仮想マシンはシャットオフされています。" + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "" +"%(name)s をリセットできません。仮想マシンは既にシャットオフされています。" + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"直接割り当てられたホスト・デバイス %(dev_name)s が VM %(vmid)s に含まれていま" +"せん。" + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"ホスト・デバイス %(dev_name)s は VM への直接割り当てを許可されていません。" + +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 グループが見つかりません。ホスト PCI パススルーでは、IOMMU グループが正" +"しく機能しなければなりません。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 "" +"デバイス %(name)s はホストで使用中である可能性があります。ゲストに接続するこ" +"とはできません。" + +#, 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 "MAC アドレスは FF:FF:FF:FF:FF:FF の形式に従っていなければなりません" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "MAC アドレス %(mac)s は既に仮想マシン %(name)s に存在します" + +msgid "Invalid MAC Address" +msgstr "MAC アドレスが無効です" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "実行中の仮想マシンの MAC アドレスは変更できません" + +#, 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 "無効なパラメーター「%(param)s」が CDROM に指定されました。" + +#, 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 "" +"テンプレートを作成するには、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 "" +"ストレージ・プールが 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 トポロジーを指定する場合、VCPU はソケット、コア、およびスレッドの積でなけ" +"ればなりません。" + +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 "" +"エクスポート・パス %(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 "ストレージ・プール 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 "" +"ストレージ・ボリューム %(name)s がストレージ・プール %(pool)s に存在しません" + +#, python-format +msgid "" +"Unable to create storage volume %(volume)s because storage pool %(pool)s is " +"not active" +msgstr "" +"ストレージ・プール %(pool)s がアクティブでないため、ストレージ・ボリューム " +"%(volume)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 "" +"ストレージ・ボリューム %(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 "" +"ストレージ・ボリューム・フォーマットがサポートされていません。有効なフォー" +"マットは 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 "1 つのパラメーター %(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 "" +"ストレージ・ボリューム「%(name)s」のクローンをプール「%(pool)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 "" +"ストレージ・ボリュームをアップロードするには、「upload」パラメーターを指定し" +"てください。" + +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 "" +"ストレージ・ボリューム %(vol)s はアップロード・プロセス中ではありません。" + +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 "" +"チャンク・データをストレージ・ボリュームにアップロードできません。詳細: " +"%(err)s。" + +#, 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 "インターフェース %(iface)s は既に存在します。" + +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 "" +"ネットワーク %(name)s を削除できません。このネットワークにリンクしている仮想" +"マシン %(vms)s とテンプレートのいずれかまたは両方がいくつかあります。" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some virtual machines " +"%(vms)s and/or templates linked to this network." +msgstr "" +"ネットワーク %(name)s を非アクティブにできません。このネットワークにリンクし" +"ている仮想マシン %(vms)s とテンプレートのいずれかまたは両方がいくつかありま" +"す。" + +#, 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 "ネットワーク %(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 "デバッグ・レポート・ファイルに名前を付ける必要があります。" + +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 "Unable to find %(item)s in datastore" +msgstr "%(item)s がデータ・ストアに見つかりません" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "URI %(uri)s が無効です" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "「%(cmd)s」コマンドの実行中、%(seconds)s 秒後にタイムアウトになります" + +msgid "Unable to choose a virtual machine name" +msgstr "仮想マシン名を選択できません" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "データ値「%(value)s」が無効です" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "データ単位「%(unit)s」が無効です" + +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 "" +"新規仮想マシン・ディスクを追加するために指定できるのはパスまたはプール/ボ" +"リュームのうち 1 つだけです" + +#, 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 は、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 "" +"YUM リポジトリーを作成または更新するには、リポジトリー・ベース URL、ミラー・" +"リスト、またはメタリンクを指定してください。" + +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 "" +"リポジトリー・メタリンクは http://、ftp://、または file:// URL でなければなり" +"ません。" + +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 "vCPU がこのシステムには大きすぎます。" + +msgid "Invalid vCPU/topology combination." +msgstr "vCPU/トポロジーの組み合わせが無効です。" + +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 "OS" + +msgid "OS Version" +msgstr "OS バージョン" + +msgid "CPUS" +msgstr "CPU" + +msgid "Memory" +msgstr "メモリー" + +msgid "Create" +msgstr "作成" + +msgid "Creating..." +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 "CPU" + +msgid "Memory (MB)" +msgstr "メモリー (MB)" + +msgid "Icon" +msgstr "アイコン" + +msgid "Device" +msgstr "デバイス" + +msgid "Path" +msgstr "パス" + +msgid "Network" +msgstr " ネットワーク" + +msgid "Type" +msgstr "タイプ" + +msgid "MAC Address" +msgstr "MAC アドレス" + +msgid "Available system users and groups" +msgstr "使用可能なシステム・ユーザーおよびグループ" + +msgid "Users" +msgstr "ユーザー" + +msgid "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 "Cancel" +msgstr "取消" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "LDAP ユーザー ID (例: foo@foo.com)" + +msgid "revert" +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」と「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 "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 "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 "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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "" +"ゲスト OS をシャットダウンせずにリセットすると、データ損失の危険があります。" +"続行しますか?" + +msgid "Shut Down Confirmation" +msgstr "シャットダウンの確認" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"ゲスト OS ではこの要求が無視される可能性があることに注意してください。続行し" +"ますか?" + +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 "link_type:" + +msgid "block:" +msgstr "ブロック:" + +msgid "drive_type:" +msgstr "drive_type:" + +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 "" +"ブリッジ VLAN タグは NetworkManager が使用可能になっている場合は正しく機能し" +"ない可能性があります。使用不可にすることを検討してください。" + +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 "ディスク・プールまたはボリュームはブランクにはできません。" + +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 "セッションがタイムアウトになりました。再度ログインしてください。" + +msgid "User Name" +msgstr "ユーザー名" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "デバイス・パス" + +msgid "iSCSI Server" +msgstr "iSCSI サーバー" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "iSCSI サーバー IP またはホスト名。空にすることはできません。" + +msgid "Server" +msgstr "サーバー" + +msgid "Port" +msgstr "ポート" + +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 "SCSI Adapter" +msgstr "SCSI アダプター" + +msgid "Please, wait..." +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 "File Path:" +msgstr "ファイル・パス:" + +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 "Processor" +msgstr "プロセッサー" + +msgid "CDROM" +msgstr "CDROM" + +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 "CPU" +msgstr "CPU" + +msgid "Disk I/O" +msgstr "ディスク入出力" + +msgid "Network I/O" +msgstr "ネットワーク入出力" + +msgid "Livetile" +msgstr "ライブタイル" + +msgid "No guests found." +msgstr "ゲストが見つかりません。" + +msgid "Shut down" +msgstr "シャットダウン" + +msgid "Restart" +msgstr "再始動" + +msgid "Basic Information" +msgstr "基本情報" + +msgid "OS Distro" +msgstr "OS ディストリビューション" + +msgid "OS Code Name" +msgstr "OS コード名" + +msgid "CPU(s)" +msgstr "CPU" + +msgid "System Statistics" +msgstr "システム統計情報" + +msgid "Update Progress" +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 "%Used" +msgstr "使用率 (%)" + +msgid "Location" +msgstr "ロケーション" + +msgid "Capacity" +msgstr "容量" + +msgid "Allocated" +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 "No templates found." +msgstr "テンプレートが見つかりません。" diff --git a/po/kimchi.pot b/plugins/kimchi/po/kimchi.pot similarity index 100% rename from po/kimchi.pot rename to plugins/kimchi/po/kimchi.pot diff --git a/plugins/kimchi/po/ko_KR.po b/plugins/kimchi/po/ko_KR.po new file mode 100644 index 000000000..37f30f0f6 --- /dev/null +++ b/plugins/kimchi/po/ko_KR.po @@ -0,0 +1,2329 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: ko_KR\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" +"Plural-Forms: nplurals=1; plural=0;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Unknown parameter %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "%(resource)s의 삭제는 허용되지 않습니다." + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s에서는 업데이트 메소드를 구현하지 않습니다." + +#, python-format +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만 지원합니다." + +#, python-format +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 "데이터 저장소가 모델 오브젝트에서 시작되지 않았습니다." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "오류 때문에 작업을 시작할 수 없음: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "Timeout of %(seconds)s seconds expired while running task '%(task)s." + +#, python-format +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에 액세스할 권한이 없습니다." + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Kimchi에 로그인하려면 %(item)s을(를) 지정하십시오." + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "지정한 LDAP 설정에서 %(user_id)s 사용자를 찾지 못했습니다." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "올바르지 않은 LDAP 구성: %(item)s : %(value)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\"는 장치 이름 문자열이어야 합니다." + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\"는 \"true\" 또는 \"false\"여야 합니다." + +#, 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 "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 "" +"하이퍼바이저가 이 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 "이미지 OS 정보를 프로브하는 중에 오류가 발생했습니다." + +msgid "No OS information found in given image." +msgstr "지정된 이미지에 OS 정보가 없습니다." + +#, 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" + +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 "VM '%(name)s'을(를) 복제할 수 없습니다. 세부사항: %(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "비지속적 가상 머신 %(name)s에 대해 올바르지 않은 조작입니다." + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "VM '%(name)s'이(가) 실행 중이 아니므로 일시중단할 수 없습니다." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "VM %(name)s을(를) 일시중단할 수 없습니다. 세부사항: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "VM '%(name)s'이(가) 일시정지되지 않았기 때문에 재개할 수 없습니다." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "VM '%(name)s'을(를) 재개할 수 없습니다. 세부사항: %(err)s" + +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 "" +"VM '%(name)s'에서는 라이브 메모리 업데이트가 지원되지 않습니다. 머신 오프라" +"인 상태로 메모리를 업데이트하여이 기능을 사용으로 설정하십시오." + +msgid "Only increase memory is allowed in active VMs" +msgstr "활성 VM에서는 메모리 늘리기만 허용됩니다." + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"라이브 메모리 업데이트의 경우 새 메모리 값은 이전 메모리 값에 1024 Mib의 배수" +"를 더한 값과같아야 합니다." + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "게스트에 1024Mib의 여유 슬롯이 없습니다." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"호스트의 libvirt 버전에서는 메모리 장치를 지원하지 않습니다. Libvirt는1.2.14" +"이상이어야 합니다." + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "메모리 장치를 연결하는 중 오류가 발생했습니다. 세부사항: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "%(name)s을(를) 시작할 수 없습니다. 가상 머신이 이미 실행 중입니다." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "%(name)s의 전원을 끌 수 없습니다. 가상 머신이 꺼진 상태입니다." + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "%(name)s을(를) 종료할 수 없습니다. 가상 머신이 꺼진 상태입니다." + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "" +"%(name)s을(를) 다시 설정할 수 없습니다. 가상 머신이 이미 꺼진 상태입니다." + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "" +"VM %(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을(를) 직접 VM에 지정할 수 없습니다." + +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 그룹을 찾을 수 없습니다. 올바르게 기능하려면 호스트 PCI pass through에 " +"IOMMU 그룹이 있어야 합니다. 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 "" +"%(name)s 장치는 호스트에서 사용 중일 수 있습니다. 게스트에 연결할 수없습니다." + +#, 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 "MAC 주소는 FF:FF:FF:FF:FF:FF 형식을 준수해야 합니다." + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "MAC 주소 %(mac)s이(가) 가상 머신 %(name)s에 이미 존재합니다." + +msgid "Invalid MAC Address" +msgstr "올바르지 않은 MAC 주소입니다." + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "실행 중인 가상 머신의 MAC 주소를 변경할 수 없습니다." + +#, 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 토폴로지를 지정할 때 VCPU는 소켓, 코어 및 스레드 제품이어야합니다." + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "CPU 토폴로지를 지정할 때 각 요소는 0보다 큰 정수여야합니다." + +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 "" +"내보내기 경로 %(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 "%(pool)s에 대해 스토리지 풀 XML을 검색하는 중에 오류가 발생했습니다." + +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 "스토리지 볼륨 %(name)s이(가) 스토리지 풀 %(pool)s에 없습니다." + +#, python-format +msgid "" +"Unable to create storage volume %(volume)s because storage pool %(pool)s is " +"not active" +msgstr "" +"스토리지 풀 %(pool)s이(가) 활성이 아니므로 스토리지 볼륨 %(volume)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 "" +"스토리지 볼륨 %(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 "" +"스토리지 볼륨 형식이 지원되지 않습니다. 올바른 형식은 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 "스토리지 볼륨 %(vol)s은(는) 업로드 프로세스의 영향을 받지 않습니다." + +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 "스토리지 볼륨에 청크 데이터를 업로드할 수 없습니다. 세부사항: %(err)s." + +#, 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 "%(iface)s 인터페이스가 이미 존재합니다." + +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 "" +"%(name)s 네트워크를 삭제할 수 없습니다. 이 네트워크에 링크된 일부 가상 머신 " +"%(vms)s 및/또는 템플리트가 있습니다." + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some virtual machines " +"%(vms)s and/or templates linked to this network." +msgstr "" +"%(name)s 네트워크를 비활성화할 수 없습니다. 이 네트워크에 링크된 일부 가상 머" +"신%(vms)s 및/또는 템플리트가 있습니다." + +#, 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 "%(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 "디버그 보고서 파일의 이름을 제공해야 합니다." + +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 "Unable to find %(item)s in datastore" +msgstr "데이터 저장소에서 %(item)s을(를) 찾을 수 없습니다." + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "올바르지 않은 URI %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "%(seconds)s초 후에 '%(cmd)s' 명령 실행 중 제한시간이 초과되었습니다." + +msgid "Unable to choose a virtual machine name" +msgstr "가상 머신 이름을 선택할 수 없습니다." + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "올바르지 않은 데이터 값 '%(value)s'입니다." + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "올바르지 않은 데이터 단위 '%(unit)s'입니다." + +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 " %(limit)s 장치의 제어기 유형 %(type)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:// 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 "" +"YUM 저장소를 작성 또는 업데이트하려면 저장소 기본 URL, 미러 목록 또는 " +"metalink를 지정하십시오." + +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 "저장소 metalink는 http://, ftp:// 또는 file:// URL이어야 합니다." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "mirrorlist 및 metalink를 동시에 지정할 수 없습니다." + +#, 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 "가상 머신 '%(vm)s'에 '%(name)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 "" +"'%(name)s' 스냅샷에 대한 가상 머신 '%(vm)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 "" +"'%(format)s' 형식의 디스크가 포함되어 있기 때문에가상 머신 '%(vm)s'의 스냅샷" +"을 작성할 수 없습니다. 'qcow2'만 지원됩니다." + +msgid "The number of vCPUs is too large for this system." +msgstr "이 시스템의 vCPU 수가 너무 큽니다." + +msgid "Invalid vCPU/topology combination." +msgstr "올바르지 않은 vCPU/토폴로지 조합입니다." + +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 "OS" + +msgid "OS Version" +msgstr "OS 버전" + +msgid "CPUS" +msgstr "CPUS" + +msgid "Memory" +msgstr "메모리" + +msgid "Create" +msgstr "작성" + +msgid "Creating..." +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 "CPU" + +msgid "Memory (MB)" +msgstr "메모리(MB)" + +msgid "Icon" +msgstr "아이콘" + +msgid "Device" +msgstr "장치" + +msgid "Path" +msgstr "경로" + +msgid "Network" +msgstr "네트워크" + +msgid "Type" +msgstr "유형" + +msgid "MAC Address" +msgstr "MAC 주소" + +msgid "Available system users and groups" +msgstr "사용 가능한 시스템 사용자 및 그룹" + +msgid "Users" +msgstr "사용자" + +msgid "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 "Cancel" +msgstr "취소" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "LDAP 사용자 ID, 예: foo@foo.com" + +msgid "revert" +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\" 및 \"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 "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 "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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "" +"게스트 OS를 종료하지 않고 다시 설정함으로 인한 데이터 손실 위험이 있습니다. " +"계속하시겠습니까?" + +msgid "Shut Down Confirmation" +msgstr "종료 확인" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "게스트 OS가 이 요청을 무시할 수 있음을 참고하십시오. 계속하시겠습니까?" + +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 "link_type:" + +msgid "block:" +msgstr "블록:" + +msgid "drive_type:" +msgstr "drive_type:" + +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 "" +"NetworkManager를 사용으로 설정하여 브릿지된 VLAN 태그가 잘 작동하지 않을 수 " +"있습니다. 사용 안함으로설정하는 것이 좋습니다." + +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 "디스크 풀 또는 볼륨은 비워둘 수 없습니다." + +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 "세션 제한시간이 초과되었습니다. 다시 로그인하십시오." + +msgid "User Name" +msgstr "사용자 이름" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "장치 경로" + +msgid "iSCSI Server" +msgstr "iSCSI 서버" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "iSCSI 서버 IP 또는 호스트 이름입니다. 비어 있지 않아야 합니다." + +msgid "Server" +msgstr "서버" + +msgid "Port" +msgstr "포트" + +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 "SCSI Adapter" +msgstr "SCSI 어댑터" + +msgid "Please, wait..." +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 "File Path:" +msgstr "파일 경로:" + +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 "Processor" +msgstr "프로세서" + +msgid "CDROM" +msgstr "CDROM" + +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 "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 "Shut down" +msgstr "시스템 종료" + +msgid "Restart" +msgstr "다시 시작" + +msgid "Basic Information" +msgstr "기본 정보" + +msgid "OS Distro" +msgstr "OS Distro" + +msgid "OS Code Name" +msgstr "OS 코드 이름" + +msgid "CPU(s)" +msgstr "CPU" + +msgid "System Statistics" +msgstr "시스템 통계" + +msgid "Update Progress" +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 "%Used" +msgstr "사용량(%)" + +msgid "Location" +msgstr "위치" + +msgid "Capacity" +msgstr "용량" + +msgid "Allocated" +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 "No templates found." +msgstr "템플리트가 없습니다." diff --git a/plugins/kimchi/po/pt_BR.po b/plugins/kimchi/po/pt_BR.po new file mode 100644 index 000000000..193792b33 --- /dev/null +++ b/plugins/kimchi/po/pt_BR.po @@ -0,0 +1,2459 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 16:10-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\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" +"Plural-Forms: nplurals=2; plural=n>1;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Parâmetro desconhecido %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "A exclusão não é permitida para %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s não implementa o método de atualização" + +#, python-format +msgid "Create is not allowed for %(resource)s" +msgstr "A criação não é permitida para %(resource)s" + +msgid "Unable to parse JSON request" +msgstr "Não é possível analisar a solicitação JSON" + +msgid "This API only supports JSON" +msgstr "Esta API suporta somente JSON" + +#, python-format +msgid "Parameters does not match requirement in schema: %(err)s" +msgstr "Os parâmetros não correspondem ao requisito no esquema: %(err)s" + +msgid "You don't have permission to perform this operation." +msgstr "Você não tem permissão para executar essa operação." + +msgid "Datastore is not initiated in the model object." +msgstr "O armazenamento de dados não é iniciado no objeto modelo." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "Não é possível iniciar a tarefa devido ao erro: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "" +"Tempo limite de %(seconds)s segundos expirou durante a execução da tarefa " +"'%(task)s'." + +#, python-format +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 a acessar o Kimchi" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Especifique %(item)s para efetuar login no Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "" +"Usuário %(user_id)s não localizado com as configurações de LDAP fornecidas." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Configuração de LDAP inválida: %(item)s: %(value)s" + +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 uma sequência de nome do dispositivo" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\" deve ser \"true\" ou \"false\"" + +#, python-format +msgid "Error while getting block devices. Details: %(err)s" +msgstr "Erro ao obter dispositivos de bloco. Detalhes: %(err)s" + +#, python-format +msgid "Error while getting block device information for %(device)s." +msgstr "" +"Erro ao obter informações sobre o dispositivo de bloco para %(device)s." + +#, python-format +msgid "Unable to find distro file: %(filename)s" +msgstr "Não é possível localizar o arquivo distro: %(filename)s" + +#, python-format +msgid "" +"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file." +msgstr "" +"Não é possível analisar o arquivo distro: %(filename)s. Certifique-se de que " +"seja um arquivo JSON." + +#, python-format +msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s" +msgstr "" +"Não é possível efetuar login no destino do host iSCSI %(portal)s. Detalhes: " +"%(err)s" + +#, python-format +msgid "Unable to login to iSCSI host %(host)s target %(target)s" +msgstr "" +"Não é possível efetuar login no destino %(target)s do host %(host)s iSCSI" + +#, python-format +msgid "Unable to find ISO file %(filename)s" +msgstr "Não é possível localizar o arquivo ISO %(filename)s" + +#, python-format +msgid "The ISO file %(filename)s is not bootable" +msgstr "O arquivo ISO %(filename)s não é inicializável" + +#, python-format +msgid "The ISO file %(filename)s does not have a valid El Torito boot record" +msgstr "" +"O arquivo ISO %(filename)s não possui um registro de inicialização El Torito " +"válido" + +#, python-format +msgid "Invalid El Torito validation entry in ISO %(filename)s" +msgstr "Entrada de validação El Torito inválida no ISO %(filename)s" + +#, python-format +msgid "Invalid El Torito boot indicator in ISO %(filename)s" +msgstr "Indicador de inicialização El Torito inválido no ISO %(filename)s" + +#, python-format +msgid "Unexpected volume type for primary volume in ISO %(filename)s" +msgstr "Tipo de volume inesperado para o volume primário no ISO %(filename)s" + +#, python-format +msgid "Bad format while reading volume descriptor in ISO %(filename)s" +msgstr "Formato inválido ao ler o descritor de volume no 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 hypervisor não possui permissão para usar este ISO %(filename)s. Considere " +"movê-lo sob /var/lib/libvirt ou configure a permissão de procura para listas " +"de controle de acesso de arquivo para o usuário '%(user)s', se possível, ou " +"inclua o '%(user)s' no grupo de caminhos ISO ou (não recomendado) 'chmod -R o" +"+x 'path_to_iso'.Detalhes: %(err)s" + +msgid "An error occurred when probing image OS information." +msgstr "Ocorreu um erro com a imagem de análise das informações de S.O." + +msgid "No OS information found in given image." +msgstr "Nenhuma informação de S.O. localizada na imagem fornecida." + +#, python-format +msgid "Unable to read image file %(filename)s" +msgstr "Não é 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 "" +"O arquivo de imagem deve ser um arquivo existente no sistema. O %(filename)s " +"não é valido válida." + +#, python-format +msgid "Virtual machine %(name)s already exists" +msgstr "A máquina virtual %(name)s já existe" + +#, python-format +msgid "Virtual machine %(name)s does not exist" +msgstr "A 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 é possível renomear a máquina virtual %(name)s. O nome %(new_name)s já " +"existe em uso ou a máquina virtual não está desligada." + +#, python-format +msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s" +msgstr "" +"Não é possível recuperar a captura de tela para a máquina virtual " +"interrompida %(name)s" + +msgid "Remote ISO image is not supported by this server." +msgstr "A imagem ISO remota não é suportada por este servidor." + +#, python-format +msgid "Screenshot is not supported on virtual machine %(name)s" +msgstr "A captura de tela não é suportada em máquina virtual %(name)s" + +#, python-format +msgid "Unable to create virtual machine %(name)s. Details: %(err)s" +msgstr "Não é 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 é 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 é possível recuperar 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 é possível se conectar à máquina virtual desligada %(name)s." + +msgid "Virtual machine name must be a string without slashes (/)" +msgstr "O nome da máquina virtual deve ser uma sequência sem barras (/)" + +#, python-format +msgid "Invalid template URI %(value)s specified for virtual machine" +msgstr "URI do modelo %(value)s inválido especificado para máquina virtual" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for virtual machine" +msgstr "" +"URI do conjunto de armazenamentos %(value)s inválido especificado para " +"máquina virtual" + +msgid "Supported virtual machine graphics are Spice or VNC" +msgstr "Os gráficos de máquina virtual suportados são Spice ou VNC" + +msgid "Graphics address to listen on must be IPv4 or IPv6" +msgstr "O endereço do gráfico para atendimento deve ser IPv4 ou IPv6" + +msgid "Specify a template to create a virtual machine from" +msgstr "Especifique um modelo para criar uma máquina virtual a partir dele" + +#, python-format +msgid "Unable to start virtual machine %(name)s. Details: %(err)s" +msgstr "Não é 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 é possível desligar a máquina virtual %(name)s. Detalhes: %(err)s" + +#, python-format +msgid "Unable to delete virtual machine %(name)s. Details: %(err)s" +msgstr "Não é possível excluir 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 é possível reconfigurar a máquina virtual %(name)s. Detalhes: %(err)s" + +msgid "User name list must be an array" +msgstr "A lista de nomes de usuário deve ser uma matriz" + +msgid "User name must be a string" +msgstr "O nome de usuário deve ser uma sequência" + +msgid "Group name list must be an array" +msgstr "A lista de nomes grupo deve ser uma matriz" + +msgid "Group name must be a string" +msgstr "O nome do grupo deve ser uma sequência" + +#, python-format +msgid "User(s) '%(users)s' do not exist" +msgstr "O(s) usuário(s) '%(users)s' não existem" + +#, python-format +msgid "Group(s) '%(groups)s' do not exist" +msgstr "O(s) grupo(s) '%(groups)s' não existem" + +#, python-format +msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s" +msgstr "Não é possível encerrar a máquina virtual %(name)s. Detalhes: %(err)s" + +msgid "The guest console password must be a string." +msgstr "A senha do console da máquina guest deve ser uma sequência." + +msgid "The life time for the guest console password must be a number." +msgstr "" +"O tempo de vida para a senha do console da máquina 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 ser interrompida antes que seja clonada." + +#, 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 é 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 "" +"Não é possível suspender a VM '%(name)s' porque ela não está em execução." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "Não é possível suspender a VM '%(name)s'. Detalhes: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "Não é possível continuar a VM '%(name)s' porque ela não está pausada." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "Não é possível continuar a VM %(name)s. Detalhes: %(err)s" + +msgid "Memory assigned is higher then the maximum allowed in the host." +msgstr "Memória designada é mais alta do que o máximo permitido no host." + +#, python-format +msgid "" +"VM '%(name)s' does not support live memory update. Update the memory with " +"the machine offline to enable this feature." +msgstr "" +"A VM '%(name)s' não suporta atualização de memória em tempo real. Atualize a " +"memória com a máquina off-line para ativar esse recurso." + +msgid "Only increase memory is allowed in active VMs" +msgstr "Somente aumentar memória é permitido em VMs ativas" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "" +"Para atualização de memória em tempo real, o novo valor de memória deve ser " +"igual ao valor de memória antigo mais múltiplos de 1024 Mib" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "Não há slots livres de 1024 Mib suficientes na máquina guest." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"A versão libvirt do host não suporta dispositivos de memória. Libvirt deve " +"ser >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "Erro ao anexar dispositivo de memória. Detalhes: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "" +"Não é possível iniciar o %(name)s. A máquina virtual já está em execução." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "Não é possível desligar o %(name)s. A máquina virtual está desligada." + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "Não é possível encerrar o %(name)s. A máquina virtual está desligada." + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "" +"Não é possível reconfigurar o %(name)s. A máquina virtual já está desligada." + +#, 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 host diretamente designado " +"%(dev_name)s." + +#, python-format +msgid "The host device %(dev_name)s is not allowed to directly assign to VM." +msgstr "" +"O dispositivo host %(dev_name)s não tem permissão para designar diretamente " +"para a VM." + +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 localizado. A passagem do PCI (Peripheral Component " +"Interconnect) host precisa do grupo IOMMU para funcionar corretamente. Ative " +"Intel VT-d ou AMD IOMMU em seu BIOS, e verifique se o Kernel está compilado " +"com suporte a IOMMU. Para a CPU (unidade central de processamento) Intel, " +"inclua intel_iommu=on em seu parâmetro do Kernel em /boot/grub2/grub.conf. " +"Para a CPU (unidade central de processamento) AMD, inclua iommu=pt iommu=1." + +msgid "\"name\" should be a device name string" +msgstr "\"name\" deve ser uma sequência de 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 "" +"O dispositivo %(name)s provavelmente está em uso pelo host. Não é possível " +"conectá-lo à máquina guest." + +#, python-format +msgid "Interface %(iface)s does not exist in virtual machine %(name)s" +msgstr "A 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 "" +"A rede %(network)s especificada para máquina virtual %(name)s não existe" + +msgid "Supported virtual machine interfaces type is only network" +msgstr "O tipo de interface de máquina virtual suportado é somente rede" + +msgid "Network name for virtual machine interface must be a string" +msgstr "O nome da rede para a interface de máquina virtual deve ser um texto" + +msgid "Invalid network model card specified for virtual machine interface" +msgstr "" +"Placa do modelo de rede inválida especificada para a interface de máquina " +"virtual" + +msgid "Specify type and network to add a new virtual machine interface" +msgstr "" +"Especifique o tipo e a rede para incluir uma nova interface de máquina " +"virtual" + +msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF" +msgstr "O Endereço MAC deve respeitar esse formato FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "O Endereço MAC %(mac)s já existe na máquina virtual %(name)s" + +msgid "Invalid MAC Address" +msgstr "Endereço MAC inválido" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "Não é possível mudar o endereço MAC de uma máquina virtual em execução" + +#, python-format +msgid "Template %(name)s already exists" +msgstr "O modelo %(name)s já existe" + +#, python-format +msgid "" +"Network '%(network)s' specified for template %(template)s does not exist" +msgstr "" +"A 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 "" +"O conjunto de armazenamentos %(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 "" +"O conjunto de armazenamentos %(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 o modelo %(template)s não está ativa" + +msgid "Template name must be a string" +msgstr "O nome de modelo deve ser um texto" + +msgid "Template icon must be a path to the image" +msgstr "O ícone de modelo deve ser um caminho para a imagem" + +msgid "Template distribution must be a string" +msgstr "A distribuição do modelo deve ser um texto" + +msgid "Template distribution version must be a string" +msgstr "A versão de 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 (unidades centrais de processamento) deve ser um número " +"inteiro maior que 0" + +msgid "Amount of memory (MB) must be an integer greater than 512" +msgstr "A quantia de memória (MB) deve ser um número inteiro maior que 512" + +msgid "Template CDROM must be a local or remote ISO file" +msgstr "O modelo CD-ROM deve ser um arquivo ISO local ou remoto" + +#, python-format +msgid "Invalid storage pool URI %(value)s specified for template" +msgstr "" +"URI do conjunto de armazenamentos %(value)s inválido 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 as 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 um modelo quando o conjunto de armazenamentos for " +"iSCSI ou SCSI" + +#, python-format +msgid "The volume %(volume)s is not in storage pool %(pool)s" +msgstr "O volume %(volume)s não está no conjunto de armazenamentos %(pool)s" + +#, python-format +msgid "Unable to create template due error: %(err)s" +msgstr "Não é possível criar o modelo devido ao erro: %(err)s" + +#, python-format +msgid "Unable to delete template due error: %(err)s" +msgstr "Não é possível excluir o modelo devido ao 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 1 GB." + +msgid "Template base image must be a valid local image file" +msgstr "A 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 é 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 da CPU, as VCPUs devem ser um produto de " +"soquetes, núcleos e encadeamentos." + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "" +"Ao especificar a topologia da CPU, cada elemento deve ser um número inteiro " +"maior que zero." + +msgid "" +"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, " +"qcow2, qed, raw, vmdk, vpc." +msgstr "" +"Formato da imagem do 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 "O conjunto de armazenamentos %(name)s já existe" + +#, python-format +msgid "Storage pool %(name)s does not exist" +msgstr "O conjunto de armazenamentos %(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 conjunto de armazenamentos %(name)s" + +#, python-format +msgid "Unable to delete active storage pool %(name)s" +msgstr "Não é possível excluir o conjunto de armazenamentos ativo %(name)s" + +#, python-format +msgid "Unable to list storage pools. Details: %(err)s" +msgstr "" +"Não é possível listar os conjuntos de armazenamentos. Detalhes: %(err)s" + +#, python-format +msgid "Unable to create storage pool %(name)s. Details: %(err)s" +msgstr "" +"Não é possível criar o conjunto de armazenamentos %(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 é possível obter o número de volumes de armazenamento no conjunto de " +"armazenamentos %(name)s. Detalhes: %(err)s" + +#, python-format +msgid "Unable to activate storage pool %(name)s. Details: %(err)s" +msgstr "" +"Não é possível ativar o conjunto de armazenamentos %(name)s. Detalhes: " +"%(err)s" + +#, python-format +msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s" +msgstr "" +"Não é possível desativar o conjunto de armazenamentos %(name)s. Detalhes: " +"%(err)s" + +#, python-format +msgid "Unable to delete storage pool %(name)s. Details: %(err)s" +msgstr "" +"Não é possível excluir o conjunto de armazenamentos %(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 é possível criar o Conjunto NFS porque 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 é possível criar o Conjunto NFS porque a montagem do caminho de " +"exportação %(path)s falhou" + +#, python-format +msgid "Unsupported storage pool type: %(type)s" +msgstr "Tipo de conjunto de armazenamentos não suportado: %(type)s" + +#, python-format +msgid "Error while retrieving storage pool XML to %(pool)s" +msgstr "Erro ao recuperar o conjunto de armazenamentos XML para %(pool)s" + +msgid "Storage pool name must be a string without slashes (/)" +msgstr "" +"O nome do conjunto de armazenamentos deve ser uma sequência sem barras (/)" + +msgid "" +"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-" +"iso" +msgstr "" +"Os tipos de conjunto de armazenamentos suportados são dir, netfs, lógico, " +"iscsi, isci e kimchiiso" + +msgid "Storage pool path must be a string" +msgstr "O caminho do storage pool deve ser um texto" + +msgid "Storage pool host must be a IP or hostname" +msgstr "O host do storage pool deve ser um IP ou nome do host" + +msgid "Storage pool device must be the absolute path to the block device" +msgstr "" +"O dispositivo do conjunto de armazenamentos deve ser o caminho absoluto para " +"o dispositivo de bloco" + +msgid "Storage pool devices parameter must be a list" +msgstr "O parâmetro de dispositivos do storage pool deve ser uma lista" + +msgid "Target IQN of an iSCSI pool must be a string" +msgstr "O IQN de destino de um conjunto iSCSI deve ser um texto" + +msgid "Port of a remote storage server must be an integer between 1 and 65535" +msgstr "" +"A porta de um servidor de armazenamento remoto deve ser um número inteiro " +"entre 1 e 65535" + +msgid "iSCSI target username must be a string" +msgstr "O nome do usuário de destino iSCSI deve ser uma sequência" + +msgid "iSCSI target password must be a string" +msgstr "A senha de destino iSCSI deve ser uma sequência" + +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 incluí-lo no " +"conjunto %(pool)s." + +#, python-format +msgid "Unable to extend logical pool %(pool)s. Details: %(err)s" +msgstr "Não é possível estender o conjunto lógico %(pool)s. Detalhes: %(err)s" + +msgid "The parameter disks only can be updated for logical storage pool." +msgstr "O parâmetro disks só pode ser atualizado para o storage pool lógico." + +msgid "The SCSI host adapter name must be a string." +msgstr "O nome do adaptador de host SCSI deve ser um texto." + +msgid "The storage pool kimchi_isos is reserved for internal use" +msgstr "O storage pool kimchi_isos está reservado para uso interno" + +#, python-format +msgid "" +"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is " +"unreachable." +msgstr "" +"Não é possível ativar o conjunto de armazenamentos NFS %(name)s. O servidor " +"NFS %(server)s é inacessível." + +#, python-format +msgid "" +"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is " +"unreachable." +msgstr "" +"Não é possível desativar o conjunto de armazenamentos NFS %(name)s. O " +"servidor NFS %(server)s é inacessível." + +#, python-format +msgid "" +"Unable to deactivate pool %(name)s as it is associated with some templates" +msgstr "" +"Não é possível desativar o conjunto %(name)s porque ele está associado com " +"alguns modelos" + +#, python-format +msgid "Unable to delete pool %(name)s as it is associated with some templates" +msgstr "" +"Não é possível excluir o conjunto %(name)s porque ele está associado com " +"alguns 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 volumes nomeado '%(name)s' já existe. Escolha outro nome para " +"criar o conjunto lógico." + +#, python-format +msgid "Unable to update database with deep scan information due error: %(err)s" +msgstr "" +"Não é possível atualizar o banco de dados com informações de varredura " +"completas devido ao erro: %(err)s" + +#, python-format +msgid "Storage volume %(name)s already exists" +msgstr "O volume de armazenamento %(name)s já existe" + +#, python-format +msgid "Storage volume %(name)s does not exist in storage pool %(pool)s" +msgstr "" +"O volume de armazenamento %(name)s não existe no conjunto de armazenamentos " +"%(pool)s" + +#, python-format +msgid "" +"Unable to create storage volume %(volume)s because storage pool %(pool)s is " +"not active" +msgstr "" +"Não é possível criar o volume de armazenamento %(volume)s porque o conjunto " +"de armazenamentos %(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 criar o volume de armazenamentos %(volume)s" + +#, python-format +msgid "" +"Unable to list storage volumes because storage pool %(pool)s is not active" +msgstr "" +"Não é possível listar os volumes de armazenamento porque o conjunto de " +"armazenamentos %(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 é possível criar o volume de armazenamento %(name)s no conjunto de " +"armazenamentos %(pool)s. Detalhes: %(err)s" + +#, python-format +msgid "" +"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s" +msgstr "" +"Não é possível listar volumes de armazenamento no conjunto de armazenamentos " +"%(pool)s. Detalhes: %(err)s" + +#, python-format +msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s" +msgstr "" +"Não é possível limpar volumes de armazenamento %(name)s. Detalhes: %(err)s" + +#, python-format +msgid "Unable to delete storage volume %(name)s. Details: %(err)s" +msgstr "" +"Não é possível excluir o volume de armazenamento %(name)s. Detalhes: %(err)s" + +#, python-format +msgid "Unable to resize storage volume %(name)s. Details: %(err)s" +msgstr "" +"Não é possível redimensionar o volume de armazenamento %(name)s. Detalhes: " +"%(err)s" + +#, python-format +msgid "Storage type %(type)s does not support volume create and delete" +msgstr "" +"O tipo de armazenamento %(type)s não suporta a criação e a exclusão de volume" + +msgid "Storage volume name must be a string" +msgstr "O nome do volume de armazenamento deve ser um texto" + +msgid "Storage volume allocation must be an integer number" +msgstr "A alocação do volume de armazenamento 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 do volume de armazenamento não suportado. Formatos válidos: bochs, " +"cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc." + +msgid "Storage volume requires a volume name" +msgstr "O volume de armazenamento requer um nome de volume" + +#, python-format +msgid "" +"Unable to update database with storage volume information due error: %(err)s" +msgstr "" +"Não é possível atualizar o banco de dados com informações de volume de " +"armazenamento devido ao erro: %(err)s" + +#, python-format +msgid "Only one of parameter %(param)s can be specified" +msgstr "Somente um dos parâmetros %(param)s pode ser especificado" + +#, python-format +msgid "Create volume from %(param)s is not supported" +msgstr "Criação de volume a partir de %(param)s não é suportada" + +msgid "Storage volume capacity must be an integer number." +msgstr "A capacidade do volume de armazenamento deve ser um número inteiro." + +msgid "Storage volume URL must be http://, https://, ftp:// or ftps://." +msgstr "" +"A URL do volume de armazenamento deve ser http://, https://, ftp:// ou " +"ftps://." + +#, python-format +msgid "Unable to access file %(url)s. Please, check it." +msgstr "Não é possível acessar o arquivo %(url)s. Verifique." + +#, python-format +msgid "" +"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: " +"%(err)s" +msgstr "" +"Não é possível clonar o volume de armazenamento '%(name)s' no conjunto " +"'%(pool)s'. Detalhes: %(err)s" + +msgid "Specify chunk data and its size to upload a file." +msgstr "" +"Especifique os dados de chunk e seu tamanho para fazer o upload de um " +"arquivo." + +msgid "In order to upload a storage volume, specify the 'upload' parameter." +msgstr "" +"Para fazer o upload de um volume de armazenamento, especifique o parâmetro " +"'upload'." + +msgid "" +"Unable to upload chunk data as it does not match with requested chunk size." +msgstr "" +"Não é possível fazer upload dos dados de chunk porque eles não correspondem " +"ao tamanho de chunk solicitado." + +#, python-format +msgid "The storage volume %(vol)s is not under an upload process." +msgstr "O volume de armazenamento %(vol)s não está sob um processo de upload." + +msgid "The upload chunk data will exceed the storage volume size." +msgstr "" +"Os dados de chunk de upload irão exceder o tamanho do volume de " +"armazenamento." + +#, python-format +msgid "Unable to upload chunk data to storage volume. Details: %(err)s." +msgstr "" +"Não é possível fazer upload dos dados de chunk para o volume de " +"armazenamento. Detalhes: %(err)s." + +#, python-format +msgid "Interface %(name)s does not exist" +msgstr "A interface %(name)s não existe" + +#, python-format +msgid "Network %(name)s already exists" +msgstr "A rede %(name)s já existe" + +#, python-format +msgid "Network %(name)s does not exist" +msgstr "A rede %(name)s não existe" + +#, python-format +msgid "Subnet %(subnet)s specified for network %(network)s is not valid." +msgstr "" +"A sub-rede %(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 uma rede em bridge %(name)s" + +#, python-format +msgid "Unable to delete active network %(name)s" +msgstr "Não é possível excluir 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 "A interface deve ser um dispositivo bare NIC, de ligação ou bridge." + +#, python-format +msgid "Unable to create network %(name)s. Details: %(err)s" +msgstr "Não é 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 é possível localizar 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 "O nome da rede deve ser uma sequência sem barras (/) ou aspas (\")" + +msgid "Supported network types are isolated, NAT and bridge" +msgstr "Os tipos de rede suportados são isolado, NAT e ponte" + +msgid "Network subnet must be a string with IP address and prefix or netmask" +msgstr "" +"A sub-rede da rede deve ser um texto com endereço IP e prefixo ou máscara de " +"rede" + +msgid "Network interface must be a string" +msgstr "A interface de rede deve ser um texto" + +msgid "Network VLAN ID must be an integer between 1 and 4094" +msgstr "O ID de VLAN da rede deve ser um número 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 é possível excluir a rede %(name)s. Existem algumas máquinas virtuais " +"%(vms)s e/ou modelos vinculados a essa 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 é possível desativar a rede %(name)s. Existem algumas máquinas virtuais " +"%(vms)s e/ou modelos vinculados a essa rede." + +#, python-format +msgid "Bridge device %(name)s can not be the trunk device of a VLAN." +msgstr "" +"O dispositivo de ponte %(name)s não pode ser o dispositivo de tronco de uma " +"VLAN." + +#, python-format +msgid "Failed to activate interface %(iface)s: %(err)s." +msgstr "Falha ao ativar a interface %(iface)s: %(err)s." + +#, python-format +msgid "" +"Failed to activate interface %(iface)s. Please check the physical link " +"status." +msgstr "Falha ao ativar a interface %(iface)s. Verifique o link físico físico." + +#, python-format +msgid "Failed to start network %(name)s. Details: %(err)s" +msgstr "Falha ao iniciar a rede %(name)s. Detalhes: %(err)s" + +#, python-format +msgid "Debug report %(name)s does not exist" +msgstr "O relatório de depuração %(name)s não existe" + +msgid "Debug report tool not found in system" +msgstr "Ferramenta de relatório de depuração não localizada no sistema" + +#, python-format +msgid "Unable to create debug report %(name)s. Details: %(err)s." +msgstr "" +"Não é possível criar o relatório de depuração %(name)s. Detalhes: %(err)s." + +#, python-format +msgid "Can not find any debug report with the given name %(name)s" +msgstr "" +"Não é possível localizar nenhum relatório de depuração com o nome fornecido " +"%(name)s" + +#, python-format +msgid "Unable to generate debug report %(name)s. Details: %(err)s" +msgstr "" +"Não é possível gerar o relatório de depuração %(name)s. Detalhes: %(err)s" + +msgid "You should give a name for the debug report file." +msgstr "" +"É necessário fornecer um nome para o relatório de arquivo de depuração." + +msgid "" +"Debug report name must be a string. Only letters, digits, underscore ('_') " +"and hyphen ('-') are allowed." +msgstr "" +"O nome do relatório de depuração deve ser uma sequência. Somente letras, " +"dígitos, sublinhado ('_') e hífen ('-') 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 depuração com o nome especificado \"%(name)s\" já existe. " +"Utilize outro relatório." + +#, python-format +msgid "Storage server %(server)s was not used by Kimchi" +msgstr "O servidor de armazenamento %(server)s não foi usado pelo Kimchi" + +#, python-format +msgid "Distro '%(name)s' does not exist" +msgstr "Distro '%(name)s' não existe" + +#, python-format +msgid "Partition %(name)s does not exist in the host" +msgstr "A partição %(name)s não existe no host" + +msgid "Unable to shutdown host machine as there are running virtual machines" +msgstr "" +"Não é possível encerrar a máquina host porque há máquinas virtuais em " +"execução" + +msgid "Unable to reboot host machine as there are running virtual machines" +msgstr "" +"Não é possível reinicializar a máquina host porque há máquinas virtuais em " +"execução" + +#, python-format +msgid "Node device '%(name)s' not found" +msgstr "Dispositivo de nó '%(name)s' não localizado" + +msgid "Conflicting flag filters specified." +msgstr "Filtros de sinalização conflitantes especificados." + +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 "O pacote %(name)s não está marcado para ser atualizado." + +#, python-format +msgid "Error while getting packages marked to be updated. Details: %(err)s" +msgstr "Erro ao obter pacotes marcados para atualização. Detalhes: %(err)s" + +msgid "There is no compatible package manager for this system." +msgstr "Não há nenhum gerenciador de pacotes compatível para este sistema." + +#, python-format +msgid "Unable to find %(item)s in datastore" +msgstr "Não é possível localizar %(item)s no armazenamento de dados" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "URI inválida %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" +"Tempo limite durante execução do comando '%(cmd)s' após %(seconds)s segundos" + +msgid "Unable to choose a virtual machine name" +msgstr "Não é possível escolher um nome de máquina virtual" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Valor dos dados inválido '%(value)s'" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Unidade de dados inválida '%(unit)s'" + +msgid "Invalid storage type. Types supported: 'cdrom', 'disk'" +msgstr "Tipo de armazenamento inválido. Tipos suportados: 'cdrom', 'disk'" + +#, 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 o dispositivo" + +msgid "Only CDROM path can be update." +msgstr "Somente o caminho CDROM pode ser atualizado." + +#, python-format +msgid "" +"The storage device %(dev_name)s does not exist in the virtual machine " +"%(vm_name)s" +msgstr "" +"O dispositivo de armazenamento %(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 o novo dispositivo de armazenamento: %(error)s" + +#, python-format +msgid "Error while updating storage device: %(error)s" +msgstr "Erro ao atualizar o dispositivo de armazenamento: %(error)s" + +#, python-format +msgid "Error while removing storage device: %(error)s" +msgstr "Erro ao remover o dispositivo de armazenamento: %(error)s" + +msgid "Do not support IDE device hot plug" +msgstr "Não suportar hot plug de dispositivo IDE" + +msgid "" +"Specify type and path or type and pool/volume to add a new virtual machine " +"disk" +msgstr "" +"Especificar tipo e caminho ou tipo e conjunto/volume para incluir um novo " +"disco de máquina virtual" + +msgid "Specify path to update virtual machine disk" +msgstr "Especifique o caminho para atualizar o disco de máquina virtual" + +#, python-format +msgid "Controller type %(type)s limitation of %(limit)s devices reached" +msgstr "" +"Limitação de tipo de controlador %(type)s de %(limit)s dispositivos atingidos" + +#, python-format +msgid "Cannot retrieve disk path information for given pool/volume: %(error)s" +msgstr "" +"Não é possível recuperar informações de caminho do disco para o conjunto/" +"volume fornecido: %(error)s" + +msgid "Volume already in use by other virtual machine." +msgstr "O volume já está sendo usado por outra máquina virtual." + +msgid "" +"Only one of path or pool/volume can be specified to add a new virtual " +"machine disk" +msgstr "" +"Apenas um caminho ou conjunto/volume podem ser especificados para inclusão " +"de um novo disco de máquina virtual" + +#, python-format +msgid "" +"Volume chosen with format %(format)s does not fit in the storage type " +"%(type)s" +msgstr "" +"O volume escolhido com o formato %(format)s não se ajusta no tipo de " +"armazenamento %(type)s" + +msgid "YUM Repository ID must be one word only string." +msgstr "O ID do Repositório YUM deve ser um texto de apenas uma palavra." + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "A 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 "" +"A configuração de repositório é um dicionário com valores específicos de " +"acordo com o tipo de repositório." + +msgid "Distribution to DEB repository must be a string" +msgstr "A distribuição para o repositório DEB deve ser um texto" + +msgid "Components to DEB repository must be listed in a array" +msgstr "Os componentes para o repositório DEB devem ser listados em uma matriz" + +msgid "Components to DEB repository must be a string" +msgstr "Os componentes para o repositório DEB devem ser um texto" + +msgid "Mirror list to repository must be a string" +msgstr "A lista de espelhos para o repositório deve ser uma sequência" + +msgid "YUM Repository name must be string." +msgstr "O nome do Repositório YUM deve ser um texto." + +msgid "GPG check must be a boolean value." +msgstr "A verificação de GPG deve ser um valor booleano." + +msgid "GPG key must be a URL pointing to the ASCII-armored file." +msgstr "" +"A chave de GPG deve ser uma URL apontando para o arquivo em 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 "O 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 "" +"Especifique a URL base do repositório, lista de espelhos ou metalink para " +"criar ou atualizar um repositório YUM." + +msgid "Repository management tool was not recognized for your system." +msgstr "" +"A ferramenta de gerenciamento de repositório não foi reconhecida por seu " +"sistema." + +#, python-format +msgid "Repository %(repo_id)s is already enabled." +msgstr "O repositório %(repo_id)s já está ativado." + +#, python-format +msgid "Repository %(repo_id)s is already disabled." +msgstr "O repositório %(repo_id)s já está desativado." + +#, 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 de repositório " +"%(repo_file)s" + +msgid "Specify repository distribution in order to create a DEB repository." +msgstr "" +"Especifique a distribuição de repositório para criar um repositório DEB." + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "Não foi possível ativar o repositório %(repo_id)s." + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "Não foi possível desativar o repositório %(repo_id)s." + +msgid "YUM Repository ID already exists" +msgstr "O ID do Repositório YUM já existe" + +msgid "YUM Repository name must be a string" +msgstr "O 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 é possível recuperar as informações do repositório. Detalhes: '%(err)s'" + +#, python-format +msgid "Unable to add repository. Details: '%(err)s'" +msgstr "Não é possível incluir repositório. Detalhes: '%(err)s'" + +#, python-format +msgid "Unable to remove repository. Details: '%(err)s'" +msgstr "Não é possível remover 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ório" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "" +"O metalink do repositório deve ser uma URL de http://, ftp:// ou file://." + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "" +"Não é possível especificar lista de espelhos e metalink ao mesmo tempo." + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "" +"A máquina virtual '%(vm)s' deve ser interrompida antes da criação de uma " +"captura instantânea nela." + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "" +"Não é possível criar captura instantânea '%(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 "" +"A captura instantânea '%(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 é possível recuperar a captura instantânea '%(name)s' na 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 é possível listar capturas instantâneas na 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 é possível excluir a captura instantânea '%(name)s' na 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 é possível recuperar a captura instantânea 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 é possível reverter a máquina virtual '%(vm)s' para a captura " +"instantânea '%(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 é possível criar a captura instantânea da máquina virtual '%(vm)s' " +"porque ela contém um disco com o formato '%(format)s'; somente 'qcow2' é " +"suportado." + +msgid "The number of vCPUs is too large for this system." +msgstr "O número de vCPUs é muito grande 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 "Esse 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 "Acessar Página Inicial" + +msgid "Create a New Virtual Machine" +msgstr "Criar uma 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 omitido, um nome será " +"escolhido com base no modelo usado." + +msgid "Template" +msgstr "Modelo" + +msgid "Please create a template first." +msgstr "Crie um modelo primeiro." + +msgid "Create a Template" +msgstr "Criar um modelo" + +msgid "Please choose a template." +msgstr "Escolha um modelo." + +msgid "OS" +msgstr "S.O." + +msgid "OS Version" +msgstr "Versão do S.O." + +msgid "CPUS" +msgstr "CPUS" + +msgid "Memory" +msgstr "Memória" + +msgid "Create" +msgstr "Criar" + +msgid "Creating..." +msgstr "Criando..." + +msgid "Edit Guest" +msgstr "Editar máquina guest" + +msgid "General" +msgstr "Geral" + +msgid "Storage" +msgstr "Armazenamento" + +msgid "Interface" +msgstr "Interface" + +msgid "Permission" +msgstr "Permissão" + +msgid "Host PCI Device" +msgstr "Dispositivo PCI do host" + +msgid "Snapshot" +msgstr "Captura instantânea" + +msgid "Name" +msgstr "Nome" + +msgid "CPUs" +msgstr "CPUs" + +msgid "Memory (MB)" +msgstr "Memória (megabyte)" + +msgid "Icon" +msgstr "Ícone" + +msgid "Device" +msgstr "Dispositivo" + +msgid "Path" +msgstr "Caminho" + +msgid "Network" +msgstr "Rede" + +msgid "Type" +msgstr "Tipo" + +msgid "MAC Address" +msgstr "Endereço MAC" + +msgid "Available system users and groups" +msgstr "Usuários e grupos do sistema disponível" + +msgid "Users" +msgstr "Usuários" + +msgid "Groups" +msgstr "Grupos" + +msgid "Selected system users and groups" +msgstr "Usuários e grupos do sistema selecionado" + +msgid "User" +msgstr "Usuário" + +msgid "All" +msgstr "Todos" + +msgid "To Add" +msgstr "Para Incluir" + +msgid "Added" +msgstr "Incluído(a)" + +msgid "filter" +msgstr "filtro" + +msgid "Product" +msgstr "Produto" + +msgid "Vendor" +msgstr "Fornecedor" + +msgid "Created" +msgstr "Criado" + +msgid "Save" +msgstr "Salvar" + +msgid "Replace" +msgstr "Substituir" + +msgid "Detach" +msgstr "Desanexar" + +msgid "Cancel" +msgstr "Cancelar" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "ID do usuário LDAP, por ex., foo@foo.com" + +msgid "revert" +msgstr "reverter" + +msgid "Add a Storage Device to VM" +msgstr "Incluir um Dispositivo de Armazenamento na VM" + +msgid "Device Type" +msgstr "Tipo de Dispositivo" + +msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported." +msgstr "" +"O tipo de dispositivo. Atualmente, \"cdrom\" e \"disk\" são suportados." + +msgid "Storage Pool" +msgstr "storage pool" + +msgid "Storage pool which volume located in" +msgstr "Conjunto de armazenamentos no qual o volume está localizado" + +msgid "Storage Volume" +msgstr "Volume de Armazenamento" + +msgid "Storage volume to be attached" +msgstr "Volume de armazenamento a ser conectado" + +msgid "File Path" +msgstr "Caminho do arquivo" + +msgid "The ISO file path in the server for CDROM." +msgstr "O caminho do arquivo ISO no servidor para o CDROM." + +msgid "Attach" +msgstr "Anexar" + +msgid "Start" +msgstr "Iniciar" + +msgid "Reset" +msgstr "Reiniciar" + +msgid "Pause" +msgstr "Pausar" + +msgid "Resume" +msgstr "Continuar" + +msgid "Power Off" +msgstr "Desligar" + +msgid "Actions" +msgstr "Ações" + +msgid "Connect" +msgstr "Conectar" + +msgid "Clone" +msgstr "Clonar" + +msgid "Edit" +msgstr "Editar" + +msgid "Shut Down" +msgstr "Encerrar" + +msgid "Delete" +msgstr "Excluir" + +msgid "The username or password you entered is incorrect. Please try again." +msgstr "O nome de usuário ou senha inserido está incorreto. Tente novamente." + +msgid "This field is required." +msgstr "Este campo é obrigatório." + +msgid "Log in" +msgstr "Efetuar login" + +msgid "Logging in..." +msgstr "Efetuando login..." + +msgid "Host" +msgstr "Host" + +msgid "Guests" +msgstr "Máquinas Guests" + +msgid "Templates" +msgstr "Modelos" + +msgid "Failed to get application configuration" +msgstr "Falha ao obter a configuração do aplicativo" + +msgid "This is not a valid Linux path" +msgstr "Este não é um caminho do Linux válido" + +msgid "This is not a valid URL." +msgstr "Esta não é uma URL válida." + +msgid "No such data available." +msgstr "Nenhum dado desse tipo disponível." + +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 é possível entrar em contato com o sistema host. Verifique se o sistema " +"host está ativo e se você tem conectividade de rede com ele. Resposta da " +"solicitação de HTTP %1. " + +msgid "Unable to read file." +msgstr "Não é possível ler o arquivo." + +msgid "Error while uploading file." +msgstr "Erro ao fazer upload do arquivo." + +msgid "Delete Confirmation" +msgstr "Confirmação de exclusão" + +msgid "OK" +msgstr "OK" + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Warning" +msgstr "Aviso" + +msgid "Cloning..." +msgstr "Clonando..." + +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 "Nenhum ISO localizado" + +msgid "This is not a valid ISO file." +msgstr "Este não é um arquivo ISO válido." + +msgid "This may take a long time. Do you want to continue?" +msgstr "Isso pode demorar. Deseja continuar?" + +msgid "This will permanently delete the template. Would you like to continue?" +msgstr "Isso excluirá permanentemente o modelo. Deseja continuar?" + +msgid "Unable to shut down system as there are some virtual machines running!" +msgstr "" +"Não é possível encerrar o sistema porque há algumas máquinas virtuais em " +"execução!" + +msgid "Max:" +msgstr "Máx.:" + +msgid "Utilization" +msgstr "Utilização" + +msgid "Available" +msgstr "Disponível" + +msgid "Read Rate" +msgstr "Taxa de leitura" + +msgid "Write Rate" +msgstr "Taxa de gravação" + +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 "" +"Encerrar ou reiniciar o host causará a perda de trabalho não salvo. " +"Continuar a encerrar/reiniciar?" + +msgid "" +"Repository will be removed permanently and can't be recovered. Do you want " +"to continue?" +msgstr "" +"O repositório será removido permanentemente e não pode ser recuperado. " +"Deseja continuar?" + +msgid "Repositories" +msgstr "Repositórios" + +msgid "ID" +msgstr "ID" + +msgid "Base URL" +msgstr "URL base" + +msgid "Is Mirror" +msgstr "É espelho" + +msgid "URL Args" +msgstr "Argumentos de URL" + +msgid "Enabled" +msgstr "Ativado" + +msgid "GPG Check" +msgstr "Verificação de GPG" + +msgid "GPG Key" +msgstr "Chave de GPG" + +msgid "Add" +msgstr "Incluir" + +msgid "Remove" +msgstr "Remover" + +msgid "Enable" +msgstr "Ativar" + +msgid "Disable" +msgstr "Desativar" + +msgid "Software Updates" +msgstr "Atualizações de software" + +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 "Falha ao recuperar informações de atualização dos pacotes." + +msgid "Failed to update package(s)." +msgstr "Falha ao atualizar pacote(s)." + +msgid "" +"Debug report will be removed permanently and can't be recovered. Do you want " +"to continue?" +msgstr "" +"O relatório de depuração será removido permanentemente e não pode ser " +"recuperado. Deseja continuar?" + +msgid "Debug Reports" +msgstr "Relatórios de depuração" + +msgid "Generated Time" +msgstr "Tempo de geração" + +msgid "Generate" +msgstr "Gerar" + +msgid "Generating..." +msgstr "Gerando..." + +msgid "Rename" +msgstr "Renomear" + +msgid "Download" +msgstr "Fazer o download" + +msgid "" +"Report name should contain only letters, digits, underscore ('_') and/or " +"hyphen ('-')." +msgstr "" +"O nome do relatório deve conter somente letras, dígitos, sublinhado ('_') e/" +"ou hífen ('-')." + +msgid "Pending..." +msgstr "Pendente..." + +msgid "Report name is the same as the original one." +msgstr "O nome do relatório é o mesmo do original." + +msgid "" +"This will delete the virtual machine and its virtual disks. This operation " +"cannot be undone. Would you like to continue?" +msgstr "" +"Isso excluirá a máquina virtual e seus discos virtuais. Esta operação não é " +"possível desfazer. Deseja continuar?" + +msgid "Power off Confirmation" +msgstr "Confirmação de Desligamento" + +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 indesejáveis, por exemplo, cache de disco " +"não alinhado armazenar em cache na máquina guest. Deseja continuar?" + +msgid "Reset Confirmation" +msgstr "Confirmação de Reconfiguração" + +msgid "" +"There is a risk of data loss caused by reset without the guest OS shutdown. " +"Would you like to continue?" +msgstr "" +"Há um risco de perda de dados causado por reconfigurar sem o encerramento do " +"sistema operacional guest. Deseja continuar?" + +msgid "Shut Down Confirmation" +msgstr "Confirmação de Encerramento" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "" +"Note que o S.O. da máquina guest pode ignorar essa solicitação. Deseja " +"continuar?" + +msgid "Virtual Machine delete Confirmation" +msgstr "Confirmação de exclusão de 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á excluí-lo. " +"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 a máquina guest de destino tiver volumes SCSI ou iSCSI, eles serão " +"clonados no conjunto de armazenamentos padrão. O mesmo ocorrerá quando o " +"conjunto de destino não tiver espaço suficiente para clonar os volumes. " +"Deseja continuar?" + +msgid "" +"This CDROM will be detached permanently and you can re-attach it. Continue " +"to detach it?" +msgstr "" +"Este CD-ROM será removido permanentemente e é possível reconectá-lo. " +"Continuar a removê-lo?" + +msgid "Attaching..." +msgstr "Conectando..." + +msgid "Replacing..." +msgstr "Substituindo..." + +msgid "Successfully attached!" +msgstr "Conectado 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 "" +"Este disco será removido permanentemente e é possível reconectá-lo. " +"Continuar a remoção?" + +msgid "interface:" +msgstr "interface:" + +msgid "address:" +msgstr "endereço:" + +msgid "link_type:" +msgstr "link_type:" + +msgid "block:" +msgstr "bloco:" + +msgid "drive_type:" +msgstr "drive_type:" + +msgid "model:" +msgstr "modelo:" + +msgid "Affected devices:" +msgstr "Dispositivos afetados:" + +msgid "The VLAN id must be between 1 and 4094." +msgstr "O ID de VLAN deve ser 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 interromperá a conectividade de rede para qualquer máquina virtual " +"que depender desta 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. Em vez de parar, essa ação o excluirá " +"permanentemente. Deseja continuar?" + +msgid "" +"The bridged VLAN tag may not work well with NetworkManager enabled. You " +"should consider disabling it." +msgstr "" +"A identificação de VLAN em ponte pode não funcionar bem com o NetworkManager " +"ativado. Você deve considerar desativá-lo." + +msgid "" +"This will permanently delete the storage pool. Would you like to continue?" +msgstr "" +"Isso excluirá permanentemente o conjunto de armazenamentos. Deseja continuar?" + +msgid "This storage pool is empty." +msgstr "Este 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á quaisquer dados contidos nele, tem " +"certeza de que deseja continuar? " + +msgid "SCSI Fibre Channel" +msgstr "Fibre Channel SCSI" + +msgid "No SCSI adapters found." +msgstr "Nenhum adaptador SCSI localizado." + +msgid "Loading iSCSI targets..." +msgstr "Carregando destinos iSCSI..." + +msgid "No iSCSI found. Please input one." +msgstr "Nenhum iSCSI localizado. Insira um." + +msgid "Failed to load iSCSI targets." +msgstr "Falha ao carregar destinos iSCSI." + +msgid "The storage pool name can not be blank." +msgstr "O nome do storage pool não pode ser em branco." + +msgid "The storage pool path can not be blank." +msgstr "O caminho do storage pool não pode ser em branco." + +msgid "NFS server mount path can not be blank." +msgstr "O caminho de montagem do servidor NFS não pode ser em branco." + +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 destino iSCSI não pode ser em branco." + +msgid "Server name can not be blank." +msgstr "O nome do servidor não pode ser em branco." + +msgid "This is not a valid Server Name or IP. Please, modify it." +msgstr "Este não é um Nome de Servidor ou IP válido. Modifique-o." + +msgid "Looking for available partitions ..." +msgstr "Procurando partições disponíveis..." + +msgid "No available partitions found." +msgstr "Nenhuma partição disponível localizada." + +msgid "" +"This storage pool is not persistent. Instead of deactivate, this action will " +"permanently delete it. Would you like to continue?" +msgstr "" +"Este storage pool não é persistente. Em vez de desativar, esta ação o " +"excluirá permanentemente. Deseja continuar?" + +msgid "Unable to retrieve partitions information." +msgstr "Não é possível recuperar as informações da partição." + +msgid "In progress..." +msgstr "Em andamento..." + +msgid "Failed!" +msgstr "Falhou!" + +msgid "CDROM path needs to be a valid local/remote path and cannot be blank." +msgstr "" +"O caminho CDROM precisa ser um caminho local/remote válido e não pode estar " +"em branco." + +msgid "Disk pool or volume cannot be blank." +msgstr "O volume ou conjunto de discos não pode estar em branco." + +msgid "Peers" +msgstr "Peers" + +msgid "Searching" +msgstr "Procurando" + +msgid "No peers found." +msgstr "Nenhum peer localizado." + +msgid "Help" +msgstr "Ajuda" + +msgid "About" +msgstr "Sobre" + +msgid "Log out" +msgstr "Efetuar logout" + +msgid "Version:" +msgstr "Versão:" + +msgid "Session timeout, please re-login." +msgstr "A sessão atingiu o tempo limite, efetue login novamente." + +msgid "User Name" +msgstr "Nome de usuário" + +msgid "Password" +msgstr "Senha" + +msgid "Generate a New Debug Report" +msgstr "Gerar um novo relatório de depuração" + +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 com base no tempo atual. O nome pode conter: letras, dígitos, " +"sublinhado (\"_\") e hífen (\"-\")." + +msgid "Rename a Debug Report" +msgstr "Renomeie um relatório de depuração" + +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 "Incluir um repositório" + +msgid "Identifier" +msgstr "Identificador" + +msgid "Single word, unique identifier for the repository." +msgstr "Identificador exclusivo com uma única palavra 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. Os protocolos suportados são http, ftp e arquivo." + +msgid "Repository is a mirror" +msgstr "O repositório é um espelho" + +msgid "Distribution" +msgstr "Distribuição" + +msgid "Distribution of the DEB repository." +msgstr "Distribuição do repositório DEB." + +msgid "Components" +msgstr "Componentes" + +msgid "List of components in DEB repository." +msgstr "Lista de componentes no repositório DEB." + +msgid "Edit Repository" +msgstr "Editar repositório" + +msgid "Mirror List URL" +msgstr "URL da lista de espelho" + +msgid "Yes" +msgstr "Sim" + +msgid "No" +msgstr "Não" + +msgid "Add a Volume to Storage Pool" +msgstr "Incluir um volume no conjunto de armazenamentos" + +msgid "Fetch from remote URL" +msgstr "Buscar a partir da URL remota" + +msgid "Enter the remote URL here." +msgstr "Inserir a URL remota aqui." + +msgid "Upload a file" +msgstr "Fazer upload de um arquivo" + +msgid "Choose the file you want to upload." +msgstr "Escolher o arquivo do qual você deseja fazer upload." + +msgid "Define a New Storage Pool" +msgstr "Definir um 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 os conjuntos de armazenamentos e não deve ser " +"vazio." + +msgid "Storage Pool Type" +msgstr "Tipo do storage pool" + +msgid "Storage Path" +msgstr "Caminho do armazenamento" + +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 exclusivo." + +msgid "" +"Kimchi will try to create the directory when it does not already exist in " +"your system." +msgstr "" +"Kimchi tentará criar o diretório quando ele não existir em 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 nome do servidor NFS. Ele pode ser inserido ou escolhido a partir do " +"histórico." + +msgid "NFS Path" +msgstr "Caminho de NFS" + +msgid "The NFS exported path on NFS server." +msgstr "O caminho exportado de NFS no servidor NFS." + +msgid "Device path" +msgstr "Caminho do dispositivo" + +msgid "iSCSI Server" +msgstr "Servidor iSCSI" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "IP ou nome do servidor iSCSI. Ele não deve ser vazio." + +msgid "Server" +msgstr "Servidor" + +msgid "Port" +msgstr "Porta" + +msgid "Target" +msgstr "Destino" + +msgid "The iSCSI target on iSCSI server" +msgstr "O destino iSCSI no servidor iSCSI" + +msgid "Add iSCSI Authentication" +msgstr "Incluir autenticação de iSCSI" + +msgid "iSCSI Authentication" +msgstr "Autenticação de iSCSI" + +msgid "SCSI Adapter" +msgstr "Adaptador SCSI" + +msgid "Please, wait..." +msgstr "Aguarde..." + +msgid "Add Template" +msgstr "Incluir modelo" + +msgid "Where is the source media for this template? " +msgstr "Onde está a mídia de origem para este modelo? " + +msgid "Local ISO Image" +msgstr "Imagem ISO local" + +msgid "Local Image File" +msgstr "Arquivo da imagem local" + +msgid "Remote ISO Image" +msgstr "Imagem ISO remota" + +msgid "Search ISOs" +msgstr "Procurar ISOs" + +msgid "The following ISOs are available:" +msgstr "Os ISOs a seguir estão disponíveis:" + +msgid "OS: " +msgstr "S.O.: " + +msgid "Version: " +msgstr "Versão: " + +msgid "Size: " +msgstr "Tamanho: " + +msgid "Search more ISOs" +msgstr "Procurar mais ISOs" + +msgid "Create Templates from Selected ISO" +msgstr "Criar modelos a partir do ISO selecionado" + +msgid "I want to use a specific ISO file" +msgstr "Eu desejo usar um arquivo ISO específico" + +msgid "File Path:" +msgstr "Caminho do arquivo: " + +msgid "Loading default remote ISOs ..." +msgstr "Carregando ISOs remotos padrão..." + +msgid "Arch: " +msgstr "Arq.: " + +msgid "I want to use a custom URL" +msgstr "Eu desejo usar uma URL customizada" + +msgid "Edit Template" +msgstr "Editar modelo" + +msgid "Processor" +msgstr "Processador" + +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 "Formato do disco" + +msgid "CPU Number" +msgstr "Número de CPU" + +msgid "Manually set CPU topology" +msgstr "Configurar manualmente a topologia da CPU" + +msgid "Cores" +msgstr "Núcleos" + +msgid "Threads" +msgstr "Encadeamentos" + +msgid "CPU" +msgstr "CPU" + +msgid "Disk I/O" +msgstr "E/S de disco" + +msgid "Network I/O" +msgstr "E/S de Rede" + +msgid "Livetile" +msgstr "Livetile" + +msgid "No guests found." +msgstr "Nenhuma máquina guest localizada." + +msgid "Shut down" +msgstr "Encerrar" + +msgid "Restart" +msgstr "Reiniciar" + +msgid "Basic Information" +msgstr "Informações básicas" + +msgid "OS Distro" +msgstr "Distribuição do S.O." + +msgid "OS Code Name" +msgstr "Nome-código do S.O." + +msgid "CPU(s)" +msgstr "CPU(s)" + +msgid "System Statistics" +msgstr "Estatísticas do sistema" + +msgid "Update Progress" +msgstr "Progresso da atualização" + +msgid "Network Name" +msgstr "Nome da rede" + +msgid "State" +msgstr "Estado" + +msgid "Network Type" +msgstr "Tipo de rede" + +msgid "Address Space" +msgstr "Espaço de endereço" + +msgid "Name should not contain '/' and '\"'." +msgstr "O nome não deve conter '/' e '\"'." + +msgid "Isolated: no external network connection" +msgstr "Isolado: nenhuma conexão de rede 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: As máquinas virtuais são conectadas à rede física diretamente" + +msgid "(No interfaces found)" +msgstr "(Nenhuma interface localizada)" + +msgid "Destination" +msgstr "Destino" + +msgid "Enable VLAN" +msgstr "Ativar VLAN" + +msgid "VLAN ID" +msgstr "ID de VLAN" + +msgid "Stop" +msgstr "Parar" + +msgid "%Used" +msgstr "%Usado" + +msgid "Location" +msgstr "Local" + +msgid "Capacity" +msgstr "Capacidade" + +msgid "Allocated" +msgstr "Alocado" + +msgid "active" +msgstr "ativo" + +msgid "inactive" +msgstr "inativo" + +msgid "Deactivate" +msgstr "Desativar" + +msgid "Activate" +msgstr "Ativar" + +msgid "Add Volume" +msgstr "Incluir volume" + +msgid "Extend" +msgstr "Estender" + +msgid "Undefine" +msgstr "Indefinir" + +msgid "Format" +msgstr "Formato" + +msgid "Allocation" +msgstr "Alocação" + +msgid "No templates found." +msgstr "Nenhum modelo localizado." diff --git a/plugins/kimchi/po/ru_RU.po b/plugins/kimchi/po/ru_RU.po new file mode 100644 index 000000000..90178b432 --- /dev/null +++ b/plugins/kimchi/po/ru_RU.po @@ -0,0 +1,2379 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: ru_RU\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" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "Неизвестный параметр %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "Удаление запрещено для %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s не имеет реализации метода обновления" + +#, python-format +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" + +#, python-format +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 "Хранилище данных в объекте модели не инициализировано." + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "Не удалось запустить задачу из-за ошибки: %(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "Во время выполнения задачи %(task)s истек тайм-аут (%(seconds)s с)." + +#, python-format +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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "Укажите %(item)s для входа в Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "Пользователь %(user_id)s не найден с указанными параметрами LDAP." + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "Недопустимая конфигурация LDAP: %(item)s : %(value)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\" должно быть строкой с именем устройства" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "Допустимые значения для \"_available_only\": \"true\" или \"false\"" + +#, 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 хоста %(host)s iSCSI" + +#, 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 "Недопустимая запись проверки 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 путь-к-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 "Не удалось прочитать файл образа %(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" + +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 "Недопустимая операция для непостоянной виртуальной машины %(name)s" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "" +"Невозможно приостановить виртуальную машину '%(name)s', поскольку она не " +"работает." + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "" +"Не удалось приостановить виртуальную машину '%(name)s'. Сведения: %(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "" +"Невозможно возобновить выполнение виртуальной машины '%(name)s', поскольку " +"она не приостановлена." + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "" +"Не удалось возобновить выполнение виртуальной машины '%(name)s'. Сведения: " +"%(err)s" + +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 "" +"Виртуальная машина '%(name)s' не поддерживает оперативное изменение объема " +"памяти. Измените объем памяти, когда машина отключена, чтобы включить эту " +"функцию." + +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 "" +"Для оперативного изменения объема памяти новое значение объема памяти должно " +"быть равно текущему объему памяти плюс величина, кратная 1024 МиБ" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "Недостаточно свободных разъемов размером 1024 МиБ в гостевой системе." + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "" +"Версия библиотеки libvirt хоста не поддерживает устройства памяти. Версия " +"библиотеки libvirt должна быть >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "Ошибка подключения устройства памяти. Сведения: %(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "Не удается запустить %(name)s. Виртуальная машина уже запущена." + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "Не удалось отключить питание %(name)s. Виртуальная машина выключена." + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "Не удается завершить работу %(name)s. Виртуальная машина выключена." + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "Не удается выполнить сброс %(name)s. Виртуальная машина уже выключена." + +#, 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. Для правильного функционирования сквозной передачи " +"PCI хоста требуется группа IOMMU. В BIOS включите поддержку Intel VT-d или " +"AMD IOMMU и проверьте, скомпилировано ли ядро ОС с поддержкой IOMMU. Для " +"процессора Intel добавьте intel_iommu=on в параметры ядра в файле /boot/" +"grub2/grub.conf. Для процессора AMD добавьте 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 "" +"Возможно, устройство %(name)s используется хостом. Его невозможно подключить " +"к гостевой системе." + +#, 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 "MAC-адрес должен иметь формат FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "MAC-адрес %(mac)s уже существует в виртуальной машине %(name)s" + +msgid "Invalid MAC Address" +msgstr "Недопустимый MAC-адрес" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "Нельзя изменить MAC-адрес работающей виртуальной машины" + +#, 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 "Число процессоров должно быть целым числом, большим 0" + +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 "Укажите том для шаблона, когда пул памяти - 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 "Размер диска должен быть целым числом больше 1 ГБ." + +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 "" +"При указании топологии процессоров количество виртуальных процессоров должно " +"быть произведением числа сокетов, ядер и нитей." + +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 "" +"Недопустимый формат образа диска. Допустимые форматы: 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 "Укажите %(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 "Ошибка получения 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 "Целевой 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 "Имя пользователя целевого объекта 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 "Том памяти %(name)s не существует в пуле памяти %(pool)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 "Укажите %(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 "" +"Формат тома памяти не поддерживается. Допустимые форматы: 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 "" +"Не удалось дублировать том памяти '%(name)s' в пуле '%(pool)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 "Для передачи тома памяти укажите параметр upload." + +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 "Том памяти %(vol)s не находится в процессе передачи." + +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 "" +"Не удалось передать данные блока передачи в том памяти. Сведения: %(err)s." + +#, 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 "Интерфейс %(iface)s уже существует." + +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 "" +"Не удалось удалить сеть %(name)s. Есть виртуальные машины %(vms)s или " +"шаблоны, связанные с данной сетью." + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some virtual machines " +"%(vms)s and/or templates linked to this network." +msgstr "" +"Не удалось деактивировать сеть %(name)s. Есть виртуальные машины %(vms)s или " +"шаблоны, связанные с данной сетью." + +#, 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 "Не удалось запустить сеть %(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 "Необходимо присвоить имя файлу отладочного отчета." + +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 "Unable to find %(item)s in datastore" +msgstr "Не найден %(item)s в хранилище данных" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "Недопустимый URI %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "" +"Истек тайм-аут во время выполнения команды '%(cmd)s' через %(seconds)s с" + +msgid "Unable to choose a virtual machine name" +msgstr "Не удалось выбрать имя виртуальной машины" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "Недопустимое значение данных '%(value)s'" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "Недопустимая единица измерения данных '%(unit)s'" + +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 "" +"Достигнуто ограничение на число устройств (%(limit)s) для типа контроллера " +"%(type)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 должен быть строкой, состоящей только из одного слова." + +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 "" +"Укажите базовый URL хранилища, список зеркал и метассылку для создания или " +"изменения хранилища YUM." + +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 "" +"Элементы конфигурации '%(items)s' не поддерживаются администратором хранилища" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "Метассылка хранилища должна быть URL http://, ftp:// или file://." + +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 "" +"Не удалось создать моментальную копию '%(name)s' виртуальной машины " +"'%(vm)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 "" +"Не удалось получить моментальную копию '%(name)s' виртуальной машины " +"'%(vm)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 "" +"Не удалось удалить моментальную копию '%(name)s' виртуальной машины " +"'%(vm)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 "Число виртуальных процессоров слишком велико для этой системы." + +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 "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 "Объем памяти (МБ)" + +msgid "Icon" +msgstr "Значок" + +msgid "Device" +msgstr "Устройство" + +msgid "Path" +msgstr "Путь" + +msgid "Network" +msgstr "Сеть" + +msgid "Type" +msgstr "Тип" + +msgid "MAC Address" +msgstr "MAC-адрес" + +msgid "Available system users and groups" +msgstr "Доступные системные пользователи и группы" + +msgid "Users" +msgstr "Пользователи" + +msgid "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 "Cancel" +msgstr "Отмена" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "ИД пользователя LDAP, например foo@foo.com" + +msgid "revert" +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\" и \"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 "Путь к файлу ISO для CDROM на сервере." + +msgid "Attach" +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 "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 "Не найден образ 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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "" +"Тег комплексной VLAN может работать неправильно с включенным NetworkManager. " +"Его рекомендуется выключить." + +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 "Загрузка целевых объектов 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 "Не указан пул или том диска." + +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 "Тайм-аут сеанса. Пожалуйста, войдите заново." + +msgid "User Name" +msgstr "Имя пользователя" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "Путь к устройству" + +msgid "iSCSI Server" +msgstr "Сервер iSCSI" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "IP-адрес или имя хоста сервера iSCSI. Не может быть пустым." + +msgid "Server" +msgstr "Сервер" + +msgid "Port" +msgstr "Порт" + +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 "SCSI Adapter" +msgstr "Адаптер SCSI" + +msgid "Please, wait..." +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 "File Path:" +msgstr "Путь к файлу:" + +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 "Processor" +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 "CPU" +msgstr "Процессор" + +msgid "Disk I/O" +msgstr "Дисковый ввод-вывод" + +msgid "Network I/O" +msgstr "Сетевой ввод-вывод" + +msgid "Livetile" +msgstr "Livetile" + +msgid "No guests found." +msgstr "Не найдены гостевые системы." + +msgid "Shut down" +msgstr "Выключен" + +msgid "Restart" +msgstr "Перезапуск" + +msgid "Basic Information" +msgstr "Базовая информация" + +msgid "OS Distro" +msgstr "Вариант ОС" + +msgid "OS Code Name" +msgstr "Кодовое имя ОС" + +msgid "CPU(s)" +msgstr "Процессоры" + +msgid "System Statistics" +msgstr "Системная статистика" + +msgid "Update Progress" +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 "%Used" +msgstr "%Используется" + +msgid "Location" +msgstr "Расположение" + +msgid "Capacity" +msgstr "Емкость" + +msgid "Allocated" +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 "No templates found." +msgstr "Не найдены шаблоны." diff --git a/plugins/kimchi/po/zh_CN.po b/plugins/kimchi/po/zh_CN.po new file mode 100644 index 000000000..9dcab181e --- /dev/null +++ b/plugins/kimchi/po/zh_CN.po @@ -0,0 +1,2219 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\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" +"Plural-Forms: nplurals=1; plural=0;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "未知参数 %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "不允许删除 %(resource)s" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s 未实现更新方法" + +#, python-format +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" + +#, python-format +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 "未在模型对象中启动数据存储器。" + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "无法启动任务,因为发生了错误:%(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "运行以下任务时,%(seconds)s 秒的超时已到期:%(task)s。" + +#, python-format +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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "指定 %(item)s 以登录 Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "找不到具有给定 LDAP 设置的用户 %(user_id)s。" + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "无效 LDAP 配置:%(item)s : %(value)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”应该为设备名字符串" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "“_available_only”应该为“true”或“false”" + +#, 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 "找不到 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 没有有效的 EI 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 "无法读取映像文件 %(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" + +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 "无法对 VM“%(name)s”进行克隆。详细信息:%(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "对非持久性虚拟机 %(name)s 的操作无效" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "无法暂挂 VM“%(name)s”,因为它未在运行。" + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "无法暂挂 VM“%(name)s”。详细信息:%(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "无法恢复 VM“%(name)s”,因为它未暂停。" + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "无法恢复 VM“%(name)s”。详细信息:%(err)s" + +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 "" +"VM“%(name)s”不支持实时内存更新。请在机器脱机的情况下更新内存以启用此功能。" + +msgid "Only increase memory is allowed in active VMs" +msgstr "仅允许在活动 VM 中增加内存" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "对于实时内存更新,新内存值必须等于旧内存值加上 1024 Mib 的倍数" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "访客中没有足够的可用插槽(大小为 1024 Mib)。" + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "主机的 Libvirt 版本不支持内存设备。Libvirt 必须 >= 1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "连接内存设备时出错。详细信息:%(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "无法启动 %(name)s。虚拟机正在运行。" + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "无法关闭 %(name)s。虚拟机已关机。" + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "无法关闭 %(name)s。虚拟机已关机。" + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "无法重置 %(name)s。虚拟机已关机。" + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "VM %(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 直接分配给 VM。" + +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 组。主机 PCI 联通需要 IOMMU 组才能正常工作。请在 BIOS 中启" +"用 Intel VT-d 或 AMD IOMMU,然后验证“内核”是否已使用 IOMMU 支持编译。对于 " +"Intel CPU,请将 intel_iommu=on 添加至 /boot/grub2/grub.conf 中的内核参数。对" +"于 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 "主机可能正在使用设备 %(name)s。无法将该设备连接到访客。" + +#, 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 "MAC 地址必须遵循格式 FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "MAC 地址 %(mac)s 已在虚拟机 %(name)s 中存在" + +msgid "Invalid MAC Address" +msgstr "无效 MAC 地址" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "无法更改正在运行的虚拟机的 MAC 地址" + +#, 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 "为 CDROM 指定的参数“%(param)s”无效。" + +#, 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 "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 "磁盘大小必须是大于 1 GB 的整数。" + +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 拓扑时,vCPU 数必须是套接字数、核心数和线程数的乘积。" + +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 "指定 %(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 "将存储池 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 "存储卷 %(name)s 在存储池 %(pool)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 "指定 %(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 "" +"存储卷格式不受支持。有效格式: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 "" +"无法对以下池中的存储卷“%(name)s”进行克隆:“%(pool)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 "要上载存储卷,请指定“upload”参数。" + +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 "存储卷 %(vol)s 未包括在上载过程中。" + +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 "无法将区块数据上载至存储卷。详细信息:%(err)s。" + +#, 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 "接口应该是空的 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 "接口 %(iface)s 已存在。" + +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 "无法删除网络 %(name)s。一些虚拟机 %(vms)s 和/或模板已链接至此网络。" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some virtual machines " +"%(vms)s and/or templates linked to this network." +msgstr "" +"无法取消激活网络 %(name)s。一些虚拟机 %(vms)s 和/或模板已链接至此网络。" + +#, 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 "未能启动网络 %(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 "您应该为调试报告文件指定名称。" + +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 "Unable to find %(item)s in datastore" +msgstr "在数据存储器中找不到 %(item)s" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "无效 URI %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "运行命令“%(cmd)s”时,在 %(seconds)s 秒后超时" + +msgid "Unable to choose a virtual machine name" +msgstr "无法选择虚拟机名称" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "无效数据值“%(value)s”" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "无效数据单元“%(unit)s”" + +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 存储库标识必须是一个单词的唯一字符串。" + +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 "指定存储库基本 URL、镜像列表或元链接以创建或更新 Yum 存储库。" + +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 "配置项:“%(items)s”不受存储库管理器支持" + +msgid "Repository metalink must be an http://, ftp:// or file:// URL." +msgstr "存储库元链接必须是 http://、ftp:// 或 file:// URL。" + +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 "无法在以下虚拟机上创建快照“%(name)s”:“%(vm)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 "无法在以下虚拟机上检索快照“%(name)s”:“%(vm)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 "无法删除以下虚拟机上的快照“%(name)s”:“%(vm)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 "vCPU 数对于此系统太大。" + +msgid "Invalid vCPU/topology combination." +msgstr "无效 vCPU/拓扑组合。" + +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 "CPUS" + +msgid "Memory" +msgstr "内存" + +msgid "Create" +msgstr "创建" + +msgid "Creating..." +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 "CPU 数" + +msgid "Memory (MB)" +msgstr "内存(MB)" + +msgid "Icon" +msgstr "图标" + +msgid "Device" +msgstr "设备" + +msgid "Path" +msgstr "路径" + +msgid "Network" +msgstr "网络" + +msgid "Type" +msgstr "类型" + +msgid "MAC Address" +msgstr "MAC 地址" + +msgid "Available system users and groups" +msgstr "可用的系统用户和组" + +msgid "Users" +msgstr "用户" + +msgid "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 "Cancel" +msgstr "取消" + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "LDAP 用户标识,如 foo@foo.com" + +msgid "revert" +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”和“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 "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 "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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "" +"在启用了网络管理器的情况下,桥接 VLAN 标记的工作情况可能不良。您应该考虑禁用" +"网络管理器。" + +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。请输入一个 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 "磁盘池或卷不能为空白。" + +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 "会话超时,请重新登录。" + +msgid "User Name" +msgstr "用户名" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "设备路径" + +msgid "iSCSI Server" +msgstr "iSCSI 服务器" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "iSCSI 服务器 IP 或主机名。它不应为空。" + +msgid "Server" +msgstr "服务器" + +msgid "Port" +msgstr "端口" + +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 "SCSI Adapter" +msgstr "SCSI 适配器" + +msgid "Please, wait..." +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 "File Path:" +msgstr "文件路径:" + +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 "Processor" +msgstr "处理器" + +msgid "CDROM" +msgstr "CDROM" + +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 "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 "Shut down" +msgstr "关闭" + +msgid "Restart" +msgstr "重新启动" + +msgid "Basic Information" +msgstr "基本信息" + +msgid "OS Distro" +msgstr "操作系统 Distro" + +msgid "OS Code Name" +msgstr "操作系统代码名称" + +msgid "CPU(s)" +msgstr "CPU" + +msgid "System Statistics" +msgstr "系统统计信息" + +msgid "Update Progress" +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 "%Used" +msgstr "已用百分比" + +msgid "Location" +msgstr "位置 " + +msgid "Capacity" +msgstr "容量" + +msgid "Allocated" +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 "No templates found." +msgstr "找不到任何模板。" diff --git a/plugins/kimchi/po/zh_TW.po b/plugins/kimchi/po/zh_TW.po new file mode 100644 index 000000000..c8c3d0e53 --- /dev/null +++ b/plugins/kimchi/po/zh_TW.po @@ -0,0 +1,2220 @@ +# English translations for kimchi package. +# Copyright (C) 2013 ORGANIZATION +# Adam Litke , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: kimchi 0.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-09-18 10:40-0300\n" +"PO-Revision-Date: 2013-07-11 17:32-0400\n" +"Last-Translator: Crístian Viana \n" +"Language-Team: English\n" +"Language: zh_TW\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" +"Plural-Forms: nplurals=1; plural=0;\n" + +#, python-format +msgid "Unknown parameter %(value)s" +msgstr "不明參數 %(value)s" + +#, python-format +msgid "Delete is not allowed for %(resource)s" +msgstr "不容許針對 %(resource)s 執行刪除作業" + +#, python-format +msgid "%(resource)s does not implement update method" +msgstr "%(resource)s 未實作更新方法" + +#, python-format +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" + +#, python-format +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 "未在模型物件中起始資料儲存庫。" + +#, python-format +msgid "Unable to start task due error: %(err)s" +msgstr "由於發生錯誤,無法開始工作:%(err)s" + +#, python-format +msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s." +msgstr "執行作業 '%(task)s' 時,超過逾時值 %(seconds)s 秒。" + +#, python-format +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" + +#, python-format +msgid "Specify %(item)s to login into Kimchi" +msgstr "指定 %(item)s 以登入 Kimchi" + +#, python-format +msgid "User %(user_id)s not found with given LDAP settings." +msgstr "找不到具有給定 LDAP 設定的使用者 %(user_id)s。" + +#, python-format +msgid "Invalid LDAP configuration: %(item)s : %(value)s" +msgstr "LDAP 配置無效:%(item)s:%(value)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\" 應該是裝置名稱字串" + +msgid "\"_available_only\" should be \"true\" or \"false\"" +msgstr "\"_available_only\" 應該是 \"true\" 或 \"false\"" + +#, 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 "找不到 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。請考量將其移動至 /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 "探測映像檔 OS 資訊時發生錯誤。" + +msgid "No OS information found in given image." +msgstr "在給定的映像檔中,找不到 OS 資訊。" + +#, 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" + +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 "無法複製 VM '%(name)s'。詳細資料:%(err)s" + +#, python-format +msgid "Invalid operation for non-persistent virtual machine %(name)s" +msgstr "針對非持續性虛擬機器 %(name)s 的作業無效" + +#, python-format +msgid "Cannot suspend VM '%(name)s' because it is not running." +msgstr "無法暫停 VM '%(name)s',因為該 VM 未處於執行中狀態。" + +#, python-format +msgid "Unable to suspend VM '%(name)s'. Details: %(err)s" +msgstr "無法暫停 VM '%(name)s'。詳細資料:%(err)s" + +#, python-format +msgid "Cannot resume VM '%(name)s' because it is not paused." +msgstr "無法回復 VM '%(name)s',因為該 VM 未處於暫停狀態。" + +#, python-format +msgid "Unable to resume VM '%(name)s'. Details: %(err)s" +msgstr "無法回復 VM '%(name)s'。詳細資料:%(err)s" + +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 "" +"VM '%(name)s' 不支援即時記憶體更新。請在機器處於離線狀態時更新記憶體,以啟用" +"此功能。" + +msgid "Only increase memory is allowed in active VMs" +msgstr "作用中的 VM 只容許增加記憶體" + +msgid "" +"For live memory update, new memory value must be equal old memory value plus " +"multiples of 1024 Mib" +msgstr "對於即時記憶體更新,新的記憶體值必須等於舊記憶體值加上1024 Mib 的倍數" + +msgid "There are not enough free slots of 1024 Mib in the guest." +msgstr "客體中可用的 1024 Mib 插槽不足。" + +msgid "" +"Host's libvirt version does not support memory devices. Libvirt must be >= " +"1.2.14" +msgstr "主機的 libvirt 版本不支援記憶體裝置。Libvirt 必須大於等於1.2.14" + +#, python-format +msgid "Error attaching memory device. Details: %(error)s" +msgstr "連接記憶體裝置時發生錯誤。詳細資料:%(error)s" + +#, python-format +msgid "Cannot start %(name)s. Virtual machine is already running." +msgstr "無法啟動 %(name)s。虛擬機器已在執行中。" + +#, python-format +msgid "Cannot power off %(name)s. Virtual machine is shut off." +msgstr "無法關閉 %(name)s。關閉虛擬機器。" + +#, python-format +msgid "Cannot shutdown %(name)s. Virtual machine is shut off." +msgstr "無法關閉 %(name)s。關閉虛擬機器。" + +#, python-format +msgid "Cannot reset %(name)s. Virtual machine is already shut off." +msgstr "無法重設 %(name)s。已關閉虛擬機器。" + +#, python-format +msgid "" +"VM %(vmid)s does not contain directly assigned host device %(dev_name)s." +msgstr "VM %(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 直接指派給 VM。" + +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 群組。主機 PCI 透通需要 IOMMU 群組才能正常運作。請在 BIOS 中啟" +"用 Intel VT-d 或 AMD IOMMU,然後驗證是否使用 IOMMU 支援編譯了核心。若為 " +"Intel CPU,請將 intel_iommu=on 新增至 /boot/grub2/grub.conf 中的核心參數。若" +"為 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 "主機可能正在使用裝置 %(name)s。無法將該裝置連接至客體。" + +#, 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 "「MAC 位址」必須遵循下列格式:FF:FF:FF:FF:FF:FF" + +#, python-format +msgid "MAC Address %(mac)s already exists in virtual machine %(name)s" +msgstr "「MAC 位址」%(mac)s 已經存在於虛擬機器 %(name)s 中" + +msgid "Invalid MAC Address" +msgstr "MAC 位址無效" + +msgid "Cannot change MAC address of a running virtual machine" +msgstr "無法變更執行中虛擬機器的 MAC 位址" + +#, 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 "磁碟大小必須是大於 1 GB 的整數。" + +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 拓蹼時,VCPU 必須是 Socket、核心及執行緒的產品。" + +msgid "" +"When specifying CPU topology, each element must be an integer greater than " +"zero." +msgstr "指定 CPU 拓蹼時,每一個元素都必須是大於 0 的整數。" + +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 "指定 %(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 "擷取儲存區 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、邏輯、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 "儲存磁區 %(name)s 不在儲存區 %(pool)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 "指定 %(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 "" +"儲存磁區格式不受支援。有效的格式: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 "若要上傳儲存磁區,請指定 'upload' 參數。" + +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 "儲存磁區 %(vol)s 未在上傳過程中。" + +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 "無法將區塊資料上傳至儲存磁區。詳細資料:%(err)s。" + +#, 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 "介面 %(iface)s 已經存在。" + +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 "" +"無法刪除網路 %(name)s。有一些虛擬機器 %(vms)s 及/或範本已鏈結至此網路。" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some virtual machines " +"%(vms)s and/or templates linked to this network." +msgstr "" +"無法取消啟動網路 %(name)s。有一些虛擬機器%(vms)s 及/或範本已鏈結至此網路。" + +#, 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 "無法啟動網路 %(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 "應該命名除錯報告檔。" + +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 "Unable to find %(item)s in datastore" +msgstr "在資料儲存庫中找不到 %(item)s" + +#, python-format +msgid "Invalid URI %(uri)s" +msgstr "無效的 URI %(uri)s" + +#, python-format +msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds" +msgstr "執行指令 '%(cmd)s' 時,在 %(seconds)s 秒之後逾時" + +msgid "Unable to choose a virtual machine name" +msgstr "無法選擇虛擬機器名稱" + +#, python-format +msgid "Invalid data value '%(value)s'" +msgstr "無效的資料值 '%(value)s'" + +#, python-format +msgid "Invalid data unit '%(unit)s'" +msgstr "無效的資料單元 '%(unit)s'" + +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:// 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 "指定儲存庫基本 URL、鏡映清單或 meta 鏈結以建立或更新 Yum 儲存庫。" + +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 "儲存庫 meta 鏈結必須是 http://、ftp:// 或 file:// URL。" + +msgid "Cannot specify mirrorlist and metalink at the same time." +msgstr "無法同時指定鏡映清單及 meta 鏈結。" + +#, python-format +msgid "" +"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it." +msgstr "必須先停止虛擬機器 '%(vm)s',然後再建立該虛擬機器的 Snapshot。" + +#, python-format +msgid "" +"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "無法在虛擬機器 '%(vm)s' 上建立 Snapshot '%(name)s'。詳細資料:%(err)s" + +#, python-format +msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'." +msgstr "Snapshot '%(name)s' 不在虛擬機器 '%(vm)s' 上。" + +#, python-format +msgid "" +"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "無法擷取虛擬機器 '%(vm)s' 上的 Snapshot '%(name)s'。詳細資料:%(err)s" + +#, python-format +msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s" +msgstr "無法列出虛擬機器 '%(vm)s' 上的 Snapshot。詳細資料:%(err)s" + +#, python-format +msgid "" +"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "無法刪除虛擬機器 '%(vm)s' 上的 Snapshot '%(name)s'。詳細資料:%(err)s" + +#, python-format +msgid "" +"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: " +"%(err)s" +msgstr "無法擷取虛擬機器 '%(vm)s' 的現行 Snapshot。詳細資料:%(err)s" + +#, python-format +msgid "" +"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: " +"%(err)s" +msgstr "無法將虛擬機器 '%(vm)s' 回復至 Snapshot '%(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' 的 Snapshot,因為該虛擬機器包含格式為 '%(format)s' " +"的磁碟;僅支援 'qcow2'。" + +msgid "The number of vCPUs is too large for this system." +msgstr "這個系統的 vCPU 數目太大。" + +msgid "Invalid vCPU/topology combination." +msgstr "vCPU/拓蹼組合無效。" + +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 "OS" + +msgid "OS Version" +msgstr "OS 版本" + +msgid "CPUS" +msgstr "CPUS" + +msgid "Memory" +msgstr "記憶體" + +msgid "Create" +msgstr "建立" + +msgid "Creating..." +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 "Snapshot" + +msgid "Name" +msgstr "名稱" + +msgid "CPUs" +msgstr "CPU" + +msgid "Memory (MB)" +msgstr "記憶體 (MB)" + +msgid "Icon" +msgstr "圖示" + +msgid "Device" +msgstr "裝置" + +msgid "Path" +msgstr "路徑" + +msgid "Network" +msgstr "網路" + +msgid "Type" +msgstr "類型" + +msgid "MAC Address" +msgstr "MAC 位址" + +msgid "Available system users and groups" +msgstr "可用的系統使用者及群組" + +msgid "Users" +msgstr "使用者" + +msgid "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 "Cancel" +msgstr "取消 " + +msgid "LDAP User ID,e.g.foo@foo.com" +msgstr "LDAP 使用者 ID,例如 foo@foo.com" + +msgid "revert" +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\" 和 \"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 "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 "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 "Repositories" +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 "Software Updates" +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 "Debug Reports" +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 "" +"如果在不關閉客體 OS 的情況下進行重設,則可能會導致資料流失。您要繼續嗎?" + +msgid "Shut Down Confirmation" +msgstr "確認關閉" + +msgid "Note the guest OS may ignore this request. Would you like to continue?" +msgstr "請注意,客體 OS 可能會忽略此要求。您要繼續嗎?" + +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,但是您可以將其重新連接。要繼續分離此 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 "" +"啟用 NetworkManager 時,橋接 VLAN 標籤可能不正常工作。您應該考量將其停用。" + +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 "磁碟儲存區或磁區不能空白。" + +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 "階段作業逾時,請重新登入。" + +msgid "User Name" +msgstr "使用者名稱" + +msgid "Password" +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 "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 "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 "Device path" +msgstr "裝置路徑" + +msgid "iSCSI Server" +msgstr "iSCSI 伺服器" + +msgid "iSCSI server IP or hostname. It should not be empty." +msgstr "iSCSI 伺服器 IP 或主機名稱。它不應該是空的。" + +msgid "Server" +msgstr "伺服器" + +msgid "Port" +msgstr "埠" + +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 "SCSI Adapter" +msgstr "SCSI 配接卡" + +msgid "Please, wait..." +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 "File Path:" +msgstr "檔案路徑:" + +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 "Processor" +msgstr "處理器" + +msgid "CDROM" +msgstr "CDROM" + +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 "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 "Shut down" +msgstr "關閉" + +msgid "Restart" +msgstr "重新啟動" + +msgid "Basic Information" +msgstr "基本資訊" + +msgid "OS Distro" +msgstr "OS Distro" + +msgid "OS Code Name" +msgstr "OS 程式碼名稱" + +msgid "CPU(s)" +msgstr "CPU" + +msgid "System Statistics" +msgstr "系統統計資料" + +msgid "Update Progress" +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 "%Used" +msgstr "已使用的百分比" + +msgid "Location" +msgstr "位置" + +msgid "Capacity" +msgstr "容量" + +msgid "Allocated" +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 "No templates found." +msgstr "找不到範本。" diff --git a/src/kimchi/repositories.py b/plugins/kimchi/repositories.py similarity index 97% rename from src/kimchi/repositories.py rename to plugins/kimchi/repositories.py index 7689151e0..c6e061f25 100644 --- a/src/kimchi/repositories.py +++ b/plugins/kimchi/repositories.py @@ -21,16 +21,16 @@ import os import time import urlparse - from ConfigParser import ConfigParser -from kimchi.basemodel import Singleton -from kimchi.config import kimchiLock -from kimchi.exception import InvalidOperation, InvalidParameter -from kimchi.exception import OperationFailed, NotFoundError, MissingParameter -from kimchi.utils import validate_repo_url -from kimchi.yumparser import get_yum_repositories, write_repo_to_file -from kimchi.yumparser import get_display_name, get_expanded_url +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 +from yumparser import get_display_name, get_expanded_url class Repositories(object): diff --git a/plugins/kimchi/root.py b/plugins/kimchi/root.py new file mode 100644 index 000000000..fb2f96628 --- /dev/null +++ b/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 import vnc +from wok.i18n import messages +from wok.root import WokRoot + +import config +import mockmodel +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/kimchi/scan.py b/plugins/kimchi/scan.py similarity index 95% rename from src/kimchi/scan.py rename to plugins/kimchi/scan.py index 86999b4b3..b475c4697 100644 --- a/src/kimchi/scan.py +++ b/plugins/kimchi/scan.py @@ -25,9 +25,9 @@ import tempfile import time +from wok.utils import wok_log -from kimchi.isoinfo import IsoImage, probe_iso -from kimchi.utils import kimchi_log +from isoinfo import IsoImage, probe_iso SCAN_IGNORE = ['/tmp/kimchi-scan-*'] @@ -58,7 +58,7 @@ def clean_stale(self, window=SCAN_TTL): self.clean_cb(transient_pool) except OSError as e: msg = "Exception %s occured when cleaning stale pool, ignore" - kimchi_log.debug(msg % e.message) + wok_log.debug(msg % e.message) def scan_dir_prepare(self, name): # clean stale scan storage pools diff --git a/src/kimchi/screenshot.py b/plugins/kimchi/screenshot.py similarity index 94% rename from src/kimchi/screenshot.py rename to plugins/kimchi/screenshot.py index e599d4017..ffe5a1a4a 100644 --- a/src/kimchi/screenshot.py +++ b/plugins/kimchi/screenshot.py @@ -25,15 +25,15 @@ import time import uuid - try: from PIL import Image except ImportError: import Image -from kimchi import config -from kimchi.utils import kimchi_log +from wok.utils import wok_log + +import config (fd, pipe) = tempfile.mkstemp() @@ -68,7 +68,7 @@ def lookup(self): if now - last_update > self.OUTDATED_SECS: self._clean_extra(self.LIVE_WINDOW) self._generate_thumbnail() - return '/data/screenshots/%s' %\ + return 'plugins/kimchi/data/screenshots/%s' %\ os.path.basename(self.info['thumbnail']) def _clean_extra(self, window=-1): @@ -164,8 +164,8 @@ def _generate_thumbnail(self): try: self._generate_scratch(thumbnail) except: - kimchi_log.error("screenshot_creation: Unable to create " - "screenshot image %s." % thumbnail) + wok_log.error("screenshot_creation: Unable to create " + "screenshot image %s." % thumbnail) else: self._create_black_image(thumbnail) @@ -178,7 +178,7 @@ def _generate_thumbnail(self): # work around pic truncate validation in thumbnail generation im.thumbnail(self.THUMBNAIL_SIZE) except Exception as e: - kimchi_log.warning("Image load with warning: %s." % e) + wok_log.warning("Image load with warning: %s." % e) im.save(thumbnail, "PNG") self.info['thumbnail'] = thumbnail diff --git a/src/kimchi/swupdate.py b/plugins/kimchi/swupdate.py similarity index 95% rename from src/kimchi/swupdate.py rename to plugins/kimchi/swupdate.py index 70db2efc8..84b927fad 100644 --- a/src/kimchi/swupdate.py +++ b/plugins/kimchi/swupdate.py @@ -20,11 +20,12 @@ import subprocess import time -from kimchi.basemodel import Singleton -from kimchi.config import kimchiLock -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.utils import kimchi_log, run_command -from kimchi.yumparser import get_yum_packages_list_update +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): @@ -49,18 +50,18 @@ def __init__(self): # correct package management system try: __import__('yum') - kimchi_log.info("Loading YumUpdate features.") + wok_log.info("Loading YumUpdate features.") self._pkg_mnger = YumUpdate() except ImportError: try: __import__('apt') - kimchi_log.info("Loading AptUpdate features.") + 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: - kimchi_log.info("Loading ZypperUpdate features.") + wok_log.info("Loading ZypperUpdate features.") self._pkg_mnger = ZypperUpdate() else: raise Exception("There is no compatible package manager " diff --git a/src/template.conf b/plugins/kimchi/template.conf similarity index 100% rename from src/template.conf rename to plugins/kimchi/template.conf diff --git a/tests/Makefile.am b/plugins/kimchi/tests/Makefile.am similarity index 97% rename from tests/Makefile.am rename to plugins/kimchi/tests/Makefile.am index 09dce6c8a..c1f6784ef 100644 --- a/tests/Makefile.am +++ b/plugins/kimchi/tests/Makefile.am @@ -31,7 +31,7 @@ do_substitution = \ -e 's,[@]prefix[@],$(prefix),g' \ -e 's,[@]datadir[@],$(datadir),g' \ -e 's,[@]PYTHON_VERSION[@],$(PYTHON_VERSION),g' \ - -e 's,[@]kimchidir[@],$(pythondir)/kimchi,g' \ + -e 's,[@]wokdir[@],$(pythondir)/wok,g' \ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' diff --git a/tests/iso_gen.py b/plugins/kimchi/tests/iso_gen.py similarity index 99% rename from tests/iso_gen.py rename to plugins/kimchi/tests/iso_gen.py index 096161d50..736c66060 100644 --- a/tests/iso_gen.py +++ b/plugins/kimchi/tests/iso_gen.py @@ -20,7 +20,8 @@ import platform import struct -from kimchi.isoinfo import IsoImage +from wok.plugins.kimchi.isoinfo import IsoImage + iso_des = [ ('openbsd', lambda v: True, diff --git a/tests/run_tests.sh.in b/plugins/kimchi/tests/run_tests.sh.in similarity index 94% rename from tests/run_tests.sh.in rename to plugins/kimchi/tests/run_tests.sh.in index d1f4b384f..beef75e92 100644 --- a/tests/run_tests.sh.in +++ b/plugins/kimchi/tests/run_tests.sh.in @@ -52,4 +52,4 @@ for ((i=0;i<${#LIST[@]};i++)); do fi done -PYTHONPATH=../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]} +PYTHONPATH=../plugins:../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]} diff --git a/tests/test_authorization.py b/plugins/kimchi/tests/test_authorization.py similarity index 62% rename from tests/test_authorization.py rename to plugins/kimchi/tests/test_authorization.py index 959dcf83d..87d68ab66 100644 --- a/tests/test_authorization.py +++ b/plugins/kimchi/tests/test_authorization.py @@ -20,10 +20,10 @@ import json import os import unittest - from functools import partial -import kimchi.mockmodel +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 @@ -41,7 +41,7 @@ def setUpModule(): global test_server, model, host, port, ssl_port patch_auth(sudo=False) - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') + model = mockmodel.MockModel('/tmp/obj-store-test') host = '127.0.0.1' port = get_free_port('http') ssl_port = get_free_port('https') @@ -64,102 +64,114 @@ def setUp(self): def test_nonroot_access(self): # Non-root users can access static host information - resp = self.request('/host', '{}', 'GET') + resp = self.request('/plugins/kimchi/host', '{}', 'GET') self.assertEquals(403, resp.status) # Non-root users can access host stats - resp = self.request('/host/stats', '{}', 'GET') + 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('/host/reboot', '{}', 'POST') + resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST') self.assertEquals(403, resp.status) - resp = self.request('/host/shutdown', '{}', 'POST') + 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('/debugreports', '{}', 'GET') + resp = self.request('/plugins/kimchi/debugreports', '{}', 'GET') self.assertEquals(403, resp.status) - resp = self.request('/debugreports', '{}', 'POST') + 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('/networks', '{}', 'GET') + resp = self.request('/plugins/kimchi/networks', '{}', 'GET') self.assertEquals(200, resp.status) - resp = self.request('/networks', '{}', 'POST') + resp = self.request('/plugins/kimchi/networks', '{}', 'POST') self.assertEquals(403, resp.status) - resp = self.request('/networks/default/activate', '{}', 'POST') + resp = self.request('/plugins/kimchi/networks/default/activate', '{}', + 'POST') self.assertEquals(403, resp.status) - resp = self.request('/networks/default', '{}', 'DELETE') + 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('/storagepools', '{}', 'GET') + resp = self.request('/plugins/kimchi/storagepools', '{}', 'GET') self.assertEquals(200, resp.status) - resp = self.request('/storagepools', '{}', 'POST') + resp = self.request('/plugins/kimchi/storagepools', '{}', 'POST') self.assertEquals(403, resp.status) - resp = self.request('/storagepools/default/activate', '{}', 'POST') + resp = self.request('/plugins/kimchi/storagepools/default/activate', + '{}', 'POST') self.assertEquals(403, resp.status) - resp = self.request('/storagepools/default', '{}', 'DELETE') + 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('/templates', '{}', 'GET') + resp = self.request('/plugins/kimchi/templates', '{}', 'GET') self.assertEquals(403, resp.status) req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(403, resp.status) - resp = self.request('/templates/test', '{}', 'PUT') + resp = self.request('/plugins/kimchi/templates/test', '{}', 'PUT') self.assertEquals(403, resp.status) - resp = self.request('/templates/test', '{}', 'DELETE') + 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': '/templates/test'}) + 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': [kimchi.mockmodel.fake_user.keys()[0]], + {'users': [mockmodel.fake_user.keys()[0]], 'groups': []}) - task_info = model.vms_create({'name': u'test-usera', - 'template': '/templates/test'}) + 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': '/templates/test'}) + 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('/vms', '{}', 'GET') + 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('/vms', req, 'POST') + 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': '/templates/test'}) + task_info = model.vms_create({ + 'name': 'kimchi-test', + 'template': '/plugins/kimchi/templates/test' + }) wait_task(model.task_lookup, task_info['id']) - resp = self.request('/vms/kimchi-test', '{}', 'PUT') + resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}', 'PUT') self.assertEquals(403, resp.status) - resp = self.request('/vms/kimchi-test', '{}', 'DELETE') + 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('/vms/test-me/start', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-me/start', '{}', 'POST') self.assertEquals(200, resp.status) - resp = self.request('/vms/test-usera/start', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-usera/start', '{}', + 'POST') self.assertEquals(403, resp.status) model.template_delete('test') diff --git a/plugins/kimchi/tests/test_config.py.in b/plugins/kimchi/tests/test_config.py.in new file mode 100644 index 000000000..9671aebb4 --- /dev/null +++ b/plugins/kimchi/tests/test_config.py.in @@ -0,0 +1,289 @@ +# +# 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 + }, + '/base64/jquery.base64.js': { + 'tools.staticfile.on': True, + 'tools.staticfile.filename': '%s/base64/jquery.base64.js' % + paths.ui_dir, + 'tools.nocache.on': True, + }, + '/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 + }, + '/fontello': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': '%s/ui/fontello' % 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 + }, + '/fontello': { + 'tools.staticdir.on': True, + 'tools.staticdir.dir': '%s/ui/fontello' % 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/tests/test_exception.py b/plugins/kimchi/tests/test_exception.py similarity index 79% rename from tests/test_exception.py rename to plugins/kimchi/tests/test_exception.py index a53301531..2b89adb59 100644 --- a/tests/test_exception.py +++ b/plugins/kimchi/tests/test_exception.py @@ -21,9 +21,8 @@ import os import unittest +from wok.plugins.kimchi import mockmodel -import kimchi.mockmodel -import kimchi.server from utils import get_free_port, patch_auth, request, run_server @@ -38,7 +37,7 @@ def setup_server(environment='development'): global test_server, model, host, port, ssl_port patch_auth() - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') + model = mockmodel.MockModel('/tmp/obj-store-test') host = '127.0.0.1' port = get_free_port('http') ssl_port = get_free_port('https') @@ -57,17 +56,21 @@ def test_production_env(self): """ setup_server('production') # test 404 - resp = json.loads(request(host, ssl_port, '/vms/blah').read()) + 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'KCHAPI0002E: Delete is not allowed for kimchiroot' + msg = u'KCHAPI0002E: 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, '/vms', '{', 'POST').read()) + resp = json.loads( + request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read() + ) msg = u'KCHAPI0006E: Unable to parse JSON request' self.assertEquals('400 Bad Request', resp.get('code')) self.assertEquals(msg, resp.get('reason')) @@ -75,7 +78,9 @@ def test_production_env(self): # test 400 missing required parameter req = json.dumps({}) - resp = json.loads(request(host, ssl_port, '/vms', req, 'POST').read()) + 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')) @@ -87,17 +92,21 @@ def test_development_env(self): """ setup_server() # test 404 - resp = json.loads(request(host, ssl_port, '/vms/blah').read()) + 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'KCHAPI0002E: Delete is not allowed for kimchiroot' + msg = u'KCHAPI0002E: 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, '/vms', '{', 'POST').read()) + resp = json.loads( + request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read() + ) msg = u'KCHAPI0006E: Unable to parse JSON request' self.assertEquals('400 Bad Request', resp.get('code')) self.assertEquals(msg, resp.get('reason')) @@ -105,7 +114,9 @@ def test_development_env(self): # test 400 missing required parameter req = json.dumps({}) - resp = json.loads(request(host, ssl_port, '/vms', req, 'POST').read()) + 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')) diff --git a/tests/test_host.py b/plugins/kimchi/tests/test_host.py similarity index 75% rename from tests/test_host.py rename to plugins/kimchi/tests/test_host.py index fe6124efd..c8c2b5815 100644 --- a/tests/test_host.py +++ b/plugins/kimchi/tests/test_host.py @@ -25,12 +25,13 @@ import tempfile import time import unittest - from functools import partial -from kimchi.mockmodel import MockModel +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 @@ -62,7 +63,7 @@ def setUp(self): self.request = partial(request, host, ssl_port) def test_hostinfo(self): - resp = self.request('/host').read() + resp = self.request('/plugins/kimchi/host').read() info = json.loads(resp) keys = ['os_distro', 'os_version', 'os_codename', 'cpu_model', 'memory', 'cpus'] @@ -78,7 +79,7 @@ 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('/host/stats').read() + resp = self.request('/plugins/kimchi/host/stats').read() stats = json.loads(resp) self.assertEquals(sorted(stats_keys), sorted(stats.keys())) @@ -94,41 +95,46 @@ def test_hoststats(self): self.assertIn('buffers', memory_stats) self.assertIn('avail', memory_stats) - resp = self.request('/host/stats/history').read() + 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('/tasks/%s' % taskid).read()) + return json.loads( + self.request('/plugins/kimchi/tasks/%s' % taskid).read() + ) - resp = self.request('/host/shutdown', '{}', 'POST') + resp = self.request('/plugins/kimchi/host/shutdown', '{}', 'POST') self.assertEquals(200, resp.status) - resp = self.request('/host/reboot', '{}', 'POST') + resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST') self.assertEquals(200, resp.status) # Test system update - resp = self.request('/host/packagesupdate', None, 'GET') + 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('/host/packagesupdate/' + name, None, 'GET') + 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('/host/swupdate', '{}', 'POST') + 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') + resp = self.request('/plugins/kimchi/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') + resp = self.request('/plugins/kimchi/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']) @@ -136,14 +142,15 @@ def _task_lookup(taskid): self.assertEquals(0, len(pkgs)) def test_host_partitions(self): - resp = self.request('/host/partitions') + 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('/host/partitions/%s' % item['name']) + resp = self.request('/plugins/kimchi/host/partitions/%s' % + item['name']) info = json.loads(resp.read()) self.assertEquals(sorted(info.keys()), sorted(keys)) @@ -152,51 +159,58 @@ def asset_devices_type(devices, dev_type): for dev in devices: self.assertEquals(dev['device_type'], dev_type) - resp = self.request('/host/devices?_cap=scsi_host') + 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('/host/devices/scsi_host2').read()) + 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('/host/devices').read()) + 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('/host/devices?_cap=%s' % dev_type) + 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('/host/devices?_passthrough=true') + 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('/host/devices?_cap=%s&_passthrough=true' % - dev_type) + 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('/host/devices?_passthrough_affected_by=%s' % - dev) + 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)) def test_get_available_passthrough_devices(self): - resp = self.request('/host/devices?_passthrough=true') + resp = self.request('/plugins/kimchi/host/devices?_passthrough=true') all_devs = [dev['name'] for dev in json.loads(resp.read())] resp = self.request( - '/host/devices?_passthrough=true&_available_only=true' + '/plugins/kimchi/host/devices?_passthrough=true&_available_only=true' ) available_devs = [dev['name'] for dev in json.loads(resp.read())] diff --git a/tests/test_mock_network.py b/plugins/kimchi/tests/test_mock_network.py similarity index 92% rename from tests/test_mock_network.py rename to plugins/kimchi/tests/test_mock_network.py index 4416c0434..4e2a93981 100644 --- a/tests/test_mock_network.py +++ b/plugins/kimchi/tests/test_mock_network.py @@ -21,10 +21,10 @@ import json import os import unittest - from functools import partial -from kimchi.mockmodel import MockModel +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 @@ -63,7 +63,9 @@ def setUp(self): 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('/interfaces?type=nic').read()) + 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', diff --git a/tests/test_mock_storagepool.py b/plugins/kimchi/tests/test_mock_storagepool.py similarity index 90% rename from tests/test_mock_storagepool.py rename to plugins/kimchi/tests/test_mock_storagepool.py index 1dc9277e1..ea9843bd2 100644 --- a/tests/test_mock_storagepool.py +++ b/plugins/kimchi/tests/test_mock_storagepool.py @@ -21,10 +21,10 @@ import json import os import unittest - from functools import partial -from kimchi.mockmodel import MockModel +from wok.plugins.kimchi.mockmodel import MockModel + from utils import get_free_port, patch_auth, request, run_server @@ -60,15 +60,21 @@ def setUp(self): model.reset() def _task_lookup(self, taskid): - return json.loads(self.request('/tasks/%s' % taskid).read()) + return json.loads( + self.request('/plugins/kimchi/tasks/%s' % taskid).read() + ) def test_storagepool(self): # MockModel always returns 2 partitions (vdx, vdz) - partitions = json.loads(self.request('/host/partitions').read()) + 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('/host/devices?_cap=fc_host').read()) + fc_devs = json.loads( + self.request('/plugins/kimchi/host/devices?_cap=fc_host').read() + ) fc_devs = [dev['name'] for dev in fc_devs] poolDefs = [ @@ -87,10 +93,10 @@ def test_storagepool(self): def _do_test(params): name = params['name'] - uri = '/storagepools/%s' % name.encode('utf-8') + uri = '/plugins/kimchi/storagepools/%s' % name.encode('utf-8') req = json.dumps(params) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, 'POST') self.assertEquals(201, resp.status) # activate the storage pool diff --git a/tests/test_mock_storagevolume.py b/plugins/kimchi/tests/test_mock_storagevolume.py similarity index 87% rename from tests/test_mock_storagevolume.py rename to plugins/kimchi/tests/test_mock_storagevolume.py index f59aa134b..9d0a5ad9c 100644 --- a/tests/test_mock_storagevolume.py +++ b/plugins/kimchi/tests/test_mock_storagevolume.py @@ -21,10 +21,10 @@ import json import os import unittest - from functools import partial -from kimchi.mockmodel import MockModel +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 @@ -61,11 +61,15 @@ def setUp(self): def test_storagevolume(self): # MockModel always returns 2 partitions (vdx, vdz) - partitions = json.loads(self.request('/host/partitions').read()) + 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('/host/devices?_cap=fc_host').read()) + fc_devs = json.loads( + self.request('/plugins/kimchi/host/devices?_cap=fc_host').read() + ) fc_devs = [dev['name'] for dev in fc_devs] poolDefs = [ @@ -84,9 +88,9 @@ def test_storagevolume(self): for pool in poolDefs: pool_name = pool['name'] - uri = '/storagepools/%s' % pool_name.encode('utf-8') + uri = '/plugins/kimchi/storagepools/%s' % pool_name.encode('utf-8') req = json.dumps(pool) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, 'POST') self.assertEquals(201, resp.status) # activate the storage pool resp = self.request(uri + '/activate', '{}', 'POST') diff --git a/tests/test_mockmodel.py b/plugins/kimchi/tests/test_mockmodel.py similarity index 81% rename from tests/test_mockmodel.py rename to plugins/kimchi/tests/test_mockmodel.py index 52972f08b..ffbf8d510 100644 --- a/tests/test_mockmodel.py +++ b/plugins/kimchi/tests/test_mockmodel.py @@ -23,10 +23,10 @@ import time import unittest +from wok.plugins.kimchi import mockmodel +from wok.plugins.kimchi.osinfo import get_template_default -import kimchi.mockmodel from utils import get_free_port, patch_auth, request, run_server, wait_task -from kimchi.osinfo import get_template_default test_server = None @@ -40,7 +40,7 @@ def setUpModule(): global host, port, ssl_port, model, test_server, fake_iso cherrypy.request.headers = {'Accept': 'application/json'} - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') + model = mockmodel.MockModel('/tmp/obj-store-test') patch_auth() port = get_free_port('http') ssl_port = get_free_port('https') @@ -64,18 +64,20 @@ def setUp(self): def test_screenshot_refresh(self): # Create a VM req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - request(host, ssl_port, '/templates', req, 'POST') + request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST') req = json.dumps({'name': 'test-vm', 'template': '/templates/test'}) - resp = request(host, ssl_port, '/vms', req, 'POST') + 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, '/vms/test-vm/start', '{}', 'POST') - resp = request(host, ssl_port, '/vms/test-vm/screenshot') + 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, '/vms/test-vm') + resp1 = request(host, ssl_port, '/plugins/kimchi/vms/test-vm') rspBody = resp1.read() testvm_Data = json.loads(rspBody) screenshotURL = testvm_Data['screenshot'] @@ -91,13 +93,14 @@ def test_screenshot_refresh(self): def test_vm_list_sorted(self): req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - request(host, ssl_port, '/templates', req, 'POST') + request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST') def add_vm(name): # Create a VM - req = json.dumps({'name': name, 'template': '/templates/test'}) - task = json.loads(request(host, ssl_port, '/vms', req, - 'POST').read()) + 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'] @@ -111,7 +114,7 @@ def test_vm_info(self): model.templates_create({'name': u'test', 'cdrom': fake_iso}) task = model.vms_create({'name': u'test-vm', - 'template': '/templates/test'}) + 'template': '/plugins/kimchi/templates/test'}) wait_task(model.task_lookup, task['id']) vms = model.vms_get_list() self.assertEquals(2, len(vms)) diff --git a/tests/test_model.py b/plugins/kimchi/tests/test_model.py similarity index 94% rename from tests/test_model.py rename to plugins/kimchi/tests/test_model.py index 7ca823a4b..55117cf6c 100644 --- a/tests/test_model.py +++ b/plugins/kimchi/tests/test_model.py @@ -27,22 +27,24 @@ 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.xmlutils.utils import xpath_get_text + +from wok.plugins.kimchi import netinfo +from wok.plugins.kimchi import osinfo +from wok.plugins.kimchi.config import kimchiPaths as paths +from wok.plugins.kimchi.model import model +from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection +from wok.plugins.kimchi.model.vms import VMModel import iso_gen -import kimchi.objectstore import utils -from kimchi import netinfo -from kimchi import osinfo -from kimchi.basemodel import Singleton -from kimchi.config import config, paths -from kimchi.exception import InvalidOperation -from kimchi.exception import InvalidParameter, NotFoundError, OperationFailed -from kimchi.model import model -from kimchi.model.libvirtconnection import LibvirtConnection -from kimchi.model.vms import VMModel -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import add_task -from kimchi.xmlutils.utils import xpath_get_text invalid_repository_urls = ['www.fedora.org', # missing protocol @@ -130,7 +132,8 @@ def test_vm_lifecycle(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'kimchi-vm', 'template': '/templates/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) @@ -266,12 +269,13 @@ def test_image_based_template(self): "icon": "images/icon-vm.png", "os_distro": "unknown", "os_version": "unknown", "disks": [{"base": vol_path, "size": 10}], - "storagepool": "/storagepools/default"} + "storagepool": "/plugins/kimchi/storagepools/default"} with inst.objstore as session: session.store('template', tmpl_name, tmpl_info) - params = {'name': 'kimchi-vm', 'template': '/templates/img-tmpl'} + 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') @@ -291,7 +295,8 @@ def test_vm_graphics(self): params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO} inst.templates_create(params) with RollbackContext() as rollback: - params = {'name': 'kimchi-vnc', 'template': '/templates/test'} + 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') @@ -301,7 +306,8 @@ def test_vm_graphics(self): self.assertEquals('127.0.0.1', info['graphics']['listen']) graphics = {'type': 'spice', 'listen': '127.0.0.1'} - params = {'name': 'kimchi-spice', 'template': '/templates/test', + params = {'name': 'kimchi-spice', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics} task2 = inst.vms_create(params) inst.task_wait(task2['id']) @@ -332,7 +338,8 @@ def test_vm_ifaces(self): rollback.prependDefer(inst.network_deactivate, net_name) for vm_name in ['kimchi-ifaces', 'kimchi-ifaces-running']: - params = {'name': vm_name, 'template': '/templates/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) @@ -435,7 +442,8 @@ def _attach_disk(expect_bus=modern_disk_bus): params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO} inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': vm_name, 'template': '/templates/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) @@ -478,8 +486,10 @@ def _attach_disk(expect_bus=modern_disk_bus): 'cdrom': old_distro_iso} inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'old_distro_template') - params = {'name': vm_name, - 'template': '/templates/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) @@ -501,7 +511,8 @@ def test_vm_cdrom(self): params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO} inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': vm_name, 'template': '/templates/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) @@ -591,7 +602,8 @@ def test_vm_storage_provisioning(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'test-vm-1', 'template': '/templates/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') @@ -648,7 +660,8 @@ def test_template_get_default_vol_format_from_conf(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'test-vm-1', 'template': '/templates/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') @@ -674,7 +687,8 @@ def test_template_creates_user_defined_vol_format_instead_default(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'test-vm-1', 'template': '/templates/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') @@ -697,7 +711,8 @@ def test_template_uses_qcow2_format_if_no_user_or_default_defined(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'test-vm-1', 'template': '/templates/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') @@ -714,7 +729,8 @@ def test_vm_memory_hotplug(self): inst.templates_create(orig_params) with RollbackContext() as rollback: - params = {'name': 'kimchi-vm1', 'template': '/templates/test'} + 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, @@ -749,8 +765,10 @@ def test_vm_edit(self): inst.templates_create(orig_params) with RollbackContext() as rollback: - params_1 = {'name': 'kimchi-vm1', 'template': '/templates/test'} - params_2 = {'name': 'kimchi-vm2', 'template': '/templates/test'} + 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, @@ -934,7 +952,8 @@ def test_delete_running_vm(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': u'kīмсhī-∨м', 'template': u'/templates/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, @@ -959,7 +978,8 @@ def test_vm_list_sorted(self): inst.templates_create(params) rollback.prependDefer(inst.template_delete, 'test') - params = {'name': 'kimchi-vm', 'template': '/templates/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') @@ -1023,16 +1043,20 @@ def test_use_test_host(self): objstore_loc=self.tmp_store) with RollbackContext() as rollback: - params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO, - 'storagepool': '/storagepools/default-pool', - 'domain': 'test', - 'arch': 'i686'} + 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': '/templates/test'} + 'template': '/plugins/kimchi/templates/test'} task = inst.vms_create(params) inst.task_wait(task['id']) rollback.prependDefer(inst.vm_delete, 'kimchi-vm') @@ -1327,7 +1351,7 @@ def create(self, params): def get_list(self): return list(self.data) - class TestModel(kimchi.basemodel.BaseModel): + class TestModel(wok.basemodel.BaseModel): def __init__(self): foo = BaseModelTests.FoosModel() super(BaseModelTests.TestModel, self).__init__([foo]) diff --git a/tests/test_model_network.py b/plugins/kimchi/tests/test_model_network.py similarity index 86% rename from tests/test_model_network.py rename to plugins/kimchi/tests/test_model_network.py index 5dbe54dc1..e4cf5ef3c 100644 --- a/tests/test_model_network.py +++ b/plugins/kimchi/tests/test_model_network.py @@ -21,11 +21,12 @@ import json import os import unittest - from functools import partial -from kimchi.model.model import Model -from kimchi.rollbackcontext import RollbackContext +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 @@ -59,11 +60,11 @@ def tearDownModule(): def _do_network_test(self, model, params): with RollbackContext() as rollback: net_name = params['name'] - uri = '/networks/%s' % net_name.encode('utf-8') + uri = '/plugins/kimchi/networks/%s' % net_name.encode('utf-8') # Create a network req = json.dumps(params) - resp = self.request('/networks', req, 'POST') + resp = self.request('/plugins/kimchi/networks', req, 'POST') rollback.prependDefer(rollback_wrapper, model.network_delete, net_name) self.assertEquals(201, resp.status) @@ -100,7 +101,7 @@ def setUp(self): self.request = partial(request, host, ssl_port) def test_get_networks(self): - networks = json.loads(self.request('/networks').read()) + networks = json.loads(self.request('/plugins/kimchi/networks').read()) self.assertIn('default', [net['name'] for net in networks]) with RollbackContext() as rollback: @@ -111,16 +112,18 @@ def test_get_networks(self): 'connection': 'nat', 'subnet': '127.0.10%i.0/24' % i}) - resp = self.request('/networks', req, 'POST') + 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('/networks').read()) + nets = json.loads(self.request('/plugins/kimchi/networks').read()) self.assertEquals(len(networks) + 5, len(nets)) - network = json.loads(self.request('/networks/network-1').read()) + 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())) @@ -134,7 +137,9 @@ def test_network_lifecycle(self): # Verify the current system has at least one interface to create a # bridged network - interfaces = json.loads(self.request('/interfaces?type=nic').read()) + 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', diff --git a/tests/test_model_storagepool.py b/plugins/kimchi/tests/test_model_storagepool.py similarity index 81% rename from tests/test_model_storagepool.py rename to plugins/kimchi/tests/test_model_storagepool.py index 70f3c7bda..5f9b9663b 100644 --- a/tests/test_model_storagepool.py +++ b/plugins/kimchi/tests/test_model_storagepool.py @@ -22,11 +22,12 @@ import os import tempfile import unittest - from functools import partial -from kimchi.model.model import Model -from kimchi.rollbackcontext import RollbackContext +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 @@ -62,7 +63,9 @@ def setUp(self): self.request = partial(request, host, ssl_port) def test_get_storagepools(self): - storagepools = json.loads(self.request('/storagepools').read()) + storagepools = json.loads( + self.request('/plugins/kimchi/storagepools').read() + ) self.assertIn('default', [pool['name'] for pool in storagepools]) with RollbackContext() as rollback: @@ -71,7 +74,8 @@ def test_get_storagepools(self): name = u'kīмсhī-storagepool-%i' % i req = json.dumps({'name': name, 'type': 'dir', 'path': '/var/lib/libvirt/images/%i' % i}) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, + 'POST') rollback.prependDefer(model.storagepool_delete, name) self.assertEquals(201, resp.status) @@ -79,11 +83,13 @@ def test_get_storagepools(self): # Pool name must be unique req = json.dumps({'name': name, 'type': 'dir', 'path': '/var/lib/libvirt/images/%i' % i}) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, + 'POST') self.assertEquals(400, resp.status) # Verify pool information - resp = self.request('/storagepools/%s' % name.encode("utf-8")) + 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', @@ -95,7 +101,9 @@ def test_get_storagepools(self): self.assertEquals(True, p['autostart']) self.assertEquals(0, p['nr_volumes']) - pools = json.loads(self.request('/storagepools').read()) + pools = json.loads( + self.request('/plugins/kimchi/storagepools').read() + ) self.assertEquals(len(storagepools) + 3, len(pools)) # Create a pool with an existing path @@ -103,12 +111,13 @@ def test_get_storagepools(self): rollback.prependDefer(os.rmdir, tmp_path) req = json.dumps({'name': 'existing_path', 'type': 'dir', 'path': tmp_path}) - resp = self.request('/storagepools', req, 'POST') + 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, '/storagepools', req, 'POST') + resp = request(host, ssl_port, '/plugins/kimchi/storagepools', req, + 'POST') self.assertEquals(400, resp.status) diff --git a/tests/test_model_storagevolume.py b/plugins/kimchi/tests/test_model_storagevolume.py similarity index 91% rename from tests/test_model_storagevolume.py rename to plugins/kimchi/tests/test_model_storagevolume.py index 82c38e28c..087dd7bd9 100644 --- a/tests/test_model_storagevolume.py +++ b/plugins/kimchi/tests/test_model_storagevolume.py @@ -22,13 +22,15 @@ import os import requests import unittest - from functools import partial -from kimchi.config import paths, READONLY_POOL_TYPE -from kimchi.model.model import Model -from kimchi.mockmodel import MockModel -from kimchi.rollbackcontext import RollbackContext +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 @@ -61,13 +63,17 @@ def tearDownModule(): def _do_volume_test(self, model, host, ssl_port, pool_name): def _task_lookup(taskid): - return json.loads(self.request('/tasks/%s' % taskid).read()) + return json.loads( + self.request('/plugins/kimchi/tasks/%s' % taskid).read() + ) - uri = '/storagepools/%s/storagevolumes' % pool_name.encode('utf-8') + uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \ + % pool_name.encode('utf-8') resp = self.request(uri) self.assertEquals(200, resp.status) - resp = self.request('/storagepools/%s' % pool_name.encode('utf-8')) + 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' @@ -84,7 +90,9 @@ def _task_lookup(taskid): 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()) + status = json.loads( + self.request('/plugins/kimchi/tasks/%s' % task_id).read() + ) self.assertEquals('finished', status['status']) vol_info = json.loads(self.request(vol_uri).read()) vol_info['name'] = vol @@ -128,7 +136,9 @@ def _task_lookup(taskid): 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()) + task = json.loads( + self.request('/plugins/kimchi/tasks/%s' % task['id']).read() + ) self.assertEquals('finished', task['status']) resp = self.request(uri + '/' + cloned_vol_name.encode('utf-8')) @@ -167,7 +177,8 @@ def _task_lookup(taskid): 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()) + status = json.loads(self.request('/plugins/kimchi/tasks/%s' % + task_id).read()) self.assertEquals('ready for upload', status['message']) # Upload volume content @@ -248,7 +259,7 @@ def setUp(self): self.request = partial(request, host, ssl_port) def test_get_storagevolume(self): - uri = '/storagepools/default/storagevolumes' + uri = '/plugins/kimchi/storagepools/default/storagevolumes' resp = self.request(uri) self.assertEquals(200, resp.status) diff --git a/tests/test_networkxml.py b/plugins/kimchi/tests/test_networkxml.py similarity index 98% rename from tests/test_networkxml.py rename to plugins/kimchi/tests/test_networkxml.py index 3706a7116..a64b6c299 100644 --- a/tests/test_networkxml.py +++ b/plugins/kimchi/tests/test_networkxml.py @@ -18,13 +18,14 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA import ipaddr -import unittest import lxml.etree as ET +import unittest -import utils +from wok.xmlutils.utils import xpath_get_text -from kimchi.xmlutils import network as nxml -from kimchi.xmlutils.utils import xpath_get_text +from wok.plugins.kimchi.xmlutils import network as nxml + +import utils class NetworkXmlTests(unittest.TestCase): diff --git a/tests/test_objectstore.py b/plugins/kimchi/tests/test_objectstore.py similarity index 97% rename from tests/test_objectstore.py rename to plugins/kimchi/tests/test_objectstore.py index f62217eb2..632786f0d 100644 --- a/tests/test_objectstore.py +++ b/plugins/kimchi/tests/test_objectstore.py @@ -23,8 +23,9 @@ import threading import unittest -from kimchi.exception import NotFoundError -from kimchi import objectstore +from wok import objectstore +from wok.exception import NotFoundError + tmpfile = None diff --git a/tests/test_osinfo.py b/plugins/kimchi/tests/test_osinfo.py similarity index 95% rename from tests/test_osinfo.py rename to plugins/kimchi/tests/test_osinfo.py index e617c54e2..bd2af5861 100644 --- a/tests/test_osinfo.py +++ b/plugins/kimchi/tests/test_osinfo.py @@ -19,9 +19,8 @@ import unittest - -from kimchi.osinfo import _get_arch, get_template_default, lookup -from kimchi.osinfo import modern_version_bases +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): diff --git a/tests/test_plugin.py b/plugins/kimchi/tests/test_plugin.py similarity index 96% rename from tests/test_plugin.py rename to plugins/kimchi/tests/test_plugin.py index 9eb6e0ae6..fc8e2770c 100644 --- a/tests/test_plugin.py +++ b/plugins/kimchi/tests/test_plugin.py @@ -20,14 +20,12 @@ import json import os import unittest - - from functools import partial +from wok.utils import get_enabled_plugins + +from wok.plugins.kimchi import mockmodel -import kimchi.mockmodel -import kimchi.server -from kimchi.utils import get_enabled_plugins import utils @@ -42,7 +40,7 @@ def setUpModule(): global test_server, model, host, port, ssl_port utils.patch_auth() - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') + 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') diff --git a/tests/test_rest.py b/plugins/kimchi/tests/test_rest.py similarity index 63% rename from tests/test_rest.py rename to plugins/kimchi/tests/test_rest.py index 3fda9a680..ee9b1495f 100644 --- a/tests/test_rest.py +++ b/plugins/kimchi/tests/test_rest.py @@ -25,15 +25,15 @@ 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 -import kimchi.mockmodel -import kimchi.server -from kimchi.osinfo import get_template_default -from kimchi.rollbackcontext import RollbackContext -from kimchi.utils import add_task from utils import get_free_port, patch_auth, request from utils import run_server, wait_task @@ -51,7 +51,7 @@ def setUpModule(): global test_server, model, host, port, ssl_port, cherrypy_port patch_auth() - model = kimchi.mockmodel.MockModel('/tmp/obj-store-test') + model = mockmodel.MockModel('/tmp/obj-store-test') host = '127.0.0.1' port = get_free_port('http') ssl_port = get_free_port('https') @@ -96,14 +96,14 @@ def assertHTTPStatus(self, code, *args): self.assertEquals(code, resp.status) def test_get_vms(self): - vms = json.loads(self.request('/vms').read()) + 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) test_users = ['root'] @@ -111,17 +111,18 @@ def test_get_vms(self): # 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': '/templates/test', - 'users': test_users, 'groups': test_groups}) - resp = self.request('/vms', req, 'POST') + 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('/vms').read()) + vms = json.loads(self.request('/plugins/kimchi/vms').read()) self.assertEquals(11, len(vms)) - vm = json.loads(self.request('/vms/vm-1').read()) + 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']) @@ -129,123 +130,130 @@ def test_get_vms(self): def test_edit_vm(self): req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) - req = json.dumps({'name': 'vm-1', 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + 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('/vms/vm-1').read()) + vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read()) self.assertEquals('vm-1', vm['name']) - resp = self.request('/vms/vm-1/start', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST') self.assertEquals(200, resp.status) req = json.dumps({'unsupported-attr': 'attr'}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'name': 'new-vm'}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'cpus': 3}) - resp = self.request('/vms/vm-1', req, 'PUT') + 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('/config/capabilities').read() + resp = self.request('/plugins/kimchi/config/capabilities').read() conf = json.loads(resp) req = json.dumps({'memory': 2048}) - resp = self.request('/vms/vm-1', req, 'PUT') + 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('/vms/vm-1', req, 'PUT') + 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('/vms/vm-1/poweroff', '{}', 'POST') + 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('/vms/vm-1', req, 'PUT') + 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('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'name': ''}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'cpus': -2}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'cpus': 'four'}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'memory': 100}) - resp = self.request('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(400, resp.status) req = json.dumps({'memory': 'ten gigas'}) - resp = self.request('/vms/vm-1', req, 'PUT') + 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('/vms/vm-1', req, 'PUT') + 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('/vms/vm-1', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT') self.assertEquals(303, resp.status) - vm = json.loads(self.request('/vms/∨м-црdαtеd', req).read()) + 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('/users', '{}', 'GET') + resp = self.request('/plugins/kimchi/users', '{}', 'GET') users = json.loads(resp.read()) req = json.dumps({'users': users}) - resp = self.request('/vms/∨м-црdαtеd', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT') self.assertEquals(200, resp.status) - info = json.loads(self.request('/vms/∨м-црdαtеd', '{}').read()) + 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('/groups', '{}', 'GET') + resp = self.request('/plugins/kimchi/groups', '{}', 'GET') groups = json.loads(resp.read()) req = json.dumps({'groups': groups}) - resp = self.request('/vms/∨м-црdαtеd', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT') self.assertEquals(200, resp.status) - info = json.loads(self.request('/vms/∨м-црdαtеd', '{}').read()) + 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('/vms/∨м-црdαtеd', req, 'PUT') + 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('/vms/∨м-црdαtеd', req, 'PUT') + resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT') self.assertEquals(400, resp.status) def test_vm_lifecycle(self): @@ -253,47 +261,51 @@ def test_vm_lifecycle(self): req = json.dumps({'name': 'test', 'disks': [{'size': 1}], 'icon': 'images/icon-debian.png', 'cdrom': fake_iso}) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Create a VM - req = json.dumps({'name': 'test-vm', 'template': '/templates/test'}) - resp = self.request('/vms', 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']) self.assertEquals(202, resp.status) # Verify the VM - vm = json.loads(self.request('/vms/test-vm').read()) + 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 = '/storagepools/default-pool/storagevolumes/%s-0.img' + 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']) # verify if poweroff command returns correct status - resp = self.request('/vms/test-vm/poweroff', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}', + 'POST') self.assertEquals(400, resp.status) # verify if shutdown command returns correct status - resp = self.request('/vms/test-vm/shutdown', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/shutdown', '{}', + 'POST') self.assertEquals(400, resp.status) # verify if reset command returns correct status - resp = self.request('/vms/test-vm/reset', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/reset', '{}', 'POST') self.assertEquals(400, resp.status) # Start the VM - resp = self.request('/vms/test-vm/start', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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']) # verify if start command returns correct status - resp = self.request('/vms/test-vm/start', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST') self.assertEquals(400, resp.status) # Test screenshot @@ -302,32 +314,36 @@ def test_vm_lifecycle(self): self.assertTrue(resp.getheader('Content-type').startswith('image')) # Clone a running VM - resp = self.request('/vms/test-vm/clone', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}', 'POST') self.assertEquals(400, resp.status) # Force poweroff the VM - resp = self.request('/vms/test-vm/poweroff', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm/clone', '{}', 'POST') + 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()) + task = json.loads( + self.request('/plugins/kimchi/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('/vms/test-vm', '{}') + resp = self.request('/plugins/kimchi/vms/test-vm', '{}') original_vm_info = json.loads(resp.read()) - resp = self.request('/vms/%s' % clone_vm_name, '{}') + resp = self.request('/plugins/kimchi/vms/%s' % clone_vm_name, '{}') self.assertEquals(200, resp.status) clone_vm_info = json.loads(resp.read()) @@ -343,21 +359,25 @@ def test_vm_lifecycle(self): # Create a snapshot on a stopped VM params = {'name': 'test-snap'} - resp = self.request('/vms/test-vm/snapshots', json.dumps(params), + 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()) + task = json.loads( + self.request('/plugins/kimchi/tasks/%s' % task['id']).read() + ) self.assertEquals('finished', task['status']) # Look up a non-existing snapshot - resp = self.request('/vms/test-vm/snapshots/snap404', '{}', 'GET') + resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/snap404', + '{}', 'GET') self.assertEquals(404, resp.status) # Look up a snapshot - resp = self.request('/vms/test-vm/snapshots/%s' % params['name'], '{}', - 'GET') + 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'])) @@ -365,90 +385,99 @@ def test_vm_lifecycle(self): self.assertEquals(u'', snap['parent']) self.assertEquals(u'shutoff', snap['state']) - resp = self.request('/vms/test-vm/snapshots', '{}', 'GET') + 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('/vms/test-vm/snapshots/current', '{}', 'GET') + 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('/vms/test-vm/snapshots', '{}', 'POST') + 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') + resp = self.request('/plugins/kimchi/tasks/%s' % task['id'], '{}', + 'GET') task = json.loads(resp.read()) self.assertEquals('finished', task['status']) - resp = self.request('/vms/test-vm/snapshots', '{}', 'GET') + 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('/vms/test-vm/snapshots/current', '{}', 'GET') + 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('/vms/test-vm/snapshots/%s/revert' % + 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('/vms/test-vm', '{}', 'GET') + 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('/vms/test-vm/snapshots/current', '{}', 'GET') + 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('/vms/test-vm/snapshots/%s' % params['name'], - '{}', 'DELETE') + resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' % + params['name'], '{}', 'DELETE') self.assertEquals(204, resp.status) # Suspend the VM - resp = self.request('/vms/test-vm', '{}', 'GET') + 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('/vms/test-vm/suspend', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}', + 'POST') self.assertEquals(400, resp.status) - resp = self.request('/vms/test-vm/start', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST') self.assertEquals(200, resp.status) - resp = self.request('/vms/test-vm', '{}', 'GET') + 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('/vms/test-vm/suspend', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}', + 'POST') self.assertEquals(200, resp.status) - resp = self.request('/vms/test-vm', '{}', 'GET') + 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('/vms/test-vm/resume', '{}', 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/resume', '{}', 'POST') self.assertEquals(200, resp.status) - resp = self.request('/vms/test-vm', '{}', 'GET') + 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('/vms/test-vm', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE') self.assertEquals(204, resp.status) # Delete the Template - resp = self.request('/templates/test', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE') self.assertEquals(204, resp.status) # Verify the volume was deleted @@ -457,87 +486,93 @@ def test_vm_lifecycle(self): def test_vm_graphics(self): # Create a Template req = json.dumps({'name': 'test', 'cdrom': fake_iso}) - resp = self.request('/templates', req, 'POST') + 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': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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': '/templates/test', + req = json.dumps({'name': 'test-vm', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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': '/templates/test', + req = json.dumps({'name': 'test-vm', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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': '/templates/test', + req = json.dumps({'name': 'test-vm', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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': '/templates/test', + req = json.dumps({'name': 'test-vm', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics}) - resp = self.request('/vms', req, 'POST') + 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': '/templates/test', + req = json.dumps({'name': 'test-vm', + 'template': '/plugins/kimchi/templates/test', 'graphics': graphics}) - resp = self.request('/vms', req, 'POST') + resp = self.request('/plugins/kimchi/vms', req, 'POST') self.assertEquals(400, resp.status) # Delete the Template - resp = self.request('/templates/test', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE') self.assertEquals(204, resp.status) def test_vm_storage_devices(self): @@ -545,25 +580,27 @@ 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Delete the template rollback.prependDefer(self.request, - '/templates/test', '{}', 'DELETE') + '/plugins/kimchi/templates/test', '{}', + 'DELETE') # Create a VM with default args req = json.dumps({'name': 'test-vm', - 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + '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, - '/vms/test-vm', '{}', 'DELETE') + rollback.prependDefer(self.request, '/plugins/kimchi/vms/test-vm', + '{}', 'DELETE') # Check storage devices - resp = self.request('/vms/test-vm/storages', '{}', 'GET') + resp = self.request('/plugins/kimchi/vms/test-vm/storages', '{}', + 'GET') devices = json.loads(resp.read()) self.assertEquals(2, len(devices)) dev_types = [] @@ -579,7 +616,8 @@ def test_vm_storage_devices(self): req = json.dumps({'dev': 'hdx', 'type': 'cdrom', 'path': '/tmp/nonexistent.iso'}) - resp = self.request('/vms/test-vm/storages', req, 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/storages', req, + 'POST') self.assertEquals(400, resp.status) # Create temp storage pool @@ -588,9 +626,10 @@ def test_vm_storage_devices(self): 'allocated': 512, 'path': '/tmp', 'type': 'dir'}) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, 'POST') self.assertEquals(201, resp.status) - resp = self.request('/storagepools/tmp/activate', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools/tmp/activate', + req, 'POST') self.assertEquals(200, resp.status) # 'name' is required for this type of volume @@ -599,16 +638,18 @@ def test_vm_storage_devices(self): 'allocation': 512, 'type': 'disk', 'format': 'raw'}) - resp = self.request('/storagepools/tmp/storagevolumes', - req, 'POST') + 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('/storagepools/tmp/storagevolumes', - req, 'POST') + resp = self.request( + '/plugins/kimchi/storagepools/tmp/storagevolumes', req, 'POST' + ) self.assertEquals(202, resp.status) time.sleep(1) @@ -619,7 +660,9 @@ def test_vm_storage_devices(self): 'pool': 'tmp', 'vol': 'attach-volume', 'path': '/tmp/existent.iso'}) - resp = self.request('/vms/test-vm/storages', req, 'POST') + resp = self.request( + '/plugins/kimchi/vms/test-vm/storages', req, 'POST' + ) self.assertEquals(400, resp.status) # Attach disk with both path and volume specified @@ -628,21 +671,27 @@ def test_vm_storage_devices(self): 'pool': 'tmp', 'vol': 'attach-volume', 'path': '/tmp/existent.iso'}) - resp = self.request('/vms/test-vm/storages', req, 'POST') + 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('/vms/test-vm/storages', req, 'POST') + 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('/vms/test-vm/storages', req, 'POST') + 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']) @@ -650,7 +699,9 @@ def test_vm_storage_devices(self): # Attach a cdrom with existent dev name req = json.dumps({'type': 'cdrom', 'path': '/tmp/existent.iso'}) - resp = self.request('/vms/test-vm/storages', req, 'POST') + 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'] @@ -658,7 +709,8 @@ def test_vm_storage_devices(self): self.assertEquals('/tmp/existent.iso', cd_info['path']) # Delete the file and cdrom rollback.prependDefer(self.request, - '/vms/test-vm/storages/hdx', '{}', 'DELETE') + '/plugins/kimchi/vms/test-vm/storages/hdx', + '{}', 'DELETE') os.remove('/tmp/existent.iso') os.remove('/tmp/attach-volume') @@ -666,27 +718,34 @@ def test_vm_storage_devices(self): cdrom = u'http://mirrors.kernel.org/fedora/releases/21/Live/'\ 'x86_64/Fedora-Live-KDE-x86_64-21-5.iso' req = json.dumps({'path': cdrom}) - resp = self.request('/vms/test-vm/storages/' + cd_dev, req, 'PUT') + 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('/vms/test-vm/storages').read()) + devs = json.loads( + self.request('/plugins/kimchi/vms/test-vm/storages').read() + ) self.assertEquals(4, len(devs)) # Detach storage cdrom - resp = self.request('/vms/test-vm/storages/' + cd_dev, - '{}', 'DELETE') + resp = self.request('/plugins/kimchi/vms/test-vm/storages/' + + cd_dev, '{}', 'DELETE') self.assertEquals(204, resp.status) # Test GET - devs = json.loads(self.request('/vms/test-vm/storages').read()) + devs = json.loads( + self.request('/plugins/kimchi/vms/test-vm/storages').read() + ) self.assertEquals(3, len(devs)) - resp = self.request('/storagepools/tmp/deactivate', {}, 'POST') + resp = self.request('/plugins/kimchi/storagepools/tmp/deactivate', + {}, 'POST') self.assertEquals(200, resp.status) - resp = self.request('/storagepools/tmp', {}, 'DELETE') + resp = self.request('/plugins/kimchi/storagepools/tmp', {}, + 'DELETE') self.assertEquals(204, resp.status) def test_vm_iface(self): @@ -694,39 +753,46 @@ 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Delete the template rollback.prependDefer(self.request, - '/templates/test', '{}', 'DELETE') + '/plugins/kimchi/templates/test', '{}', + 'DELETE') # Create a VM with default args req = json.dumps({'name': 'test-vm', - 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + '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, - '/vms/test-vm', '{}', 'DELETE') + '/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('/networks', req, 'POST') + resp = self.request('/plugins/kimchi/networks', req, 'POST') self.assertEquals(201, resp.status) # Delete the network rollback.prependDefer(self.request, - '/networks/test-network', '{}', 'DELETE') + '/plugins/kimchi/networks/test-network', + '{}', 'DELETE') - ifaces = json.loads(self.request('/vms/test-vm/ifaces').read()) + 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('/vms/test-vm/ifaces/%s' % - iface['mac']).read()) + 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'), @@ -735,14 +801,16 @@ def test_vm_iface(self): # try to attach an interface without specifying 'model' req = json.dumps({'type': 'network'}) - resp = self.request('/vms/test-vm/ifaces', req, 'POST') + 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('/vms/test-vm/ifaces', req, 'POST') + resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req, + 'POST') self.assertEquals(201, resp.status) iface = json.loads(resp.read()) @@ -755,38 +823,44 @@ def test_vm_iface(self): newMacAddr = '54:50:e3:44:8a:af' req = json.dumps({"network": "default", "model": "virtio", "type": "network", "mac": newMacAddr}) - resp = self.request('/vms/test-vm/ifaces/%s' % iface['mac'], - req, 'PUT') + resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' % + iface['mac'], req, 'PUT') self.assertEquals(303, resp.status) - iface = json.loads(self.request('/vms/test-vm/ifaces/%s' % - newMacAddr).read()) + iface = json.loads( + self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' % + newMacAddr).read() + ) self.assertEquals(newMacAddr, iface['mac']) # Start the VM - resp = self.request('/vms/test-vm/start', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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']) # Check for an IP address - iface = json.loads(self.request('/vms/test-vm/ifaces/%s' % - newMacAddr).read()) + iface = json.loads( + self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' % + newMacAddr).read() + ) self.assertTrue(len(iface['ips']) > 0) # Force poweroff the VM - resp = self.request('/vms/test-vm/poweroff', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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']) # detach network interface from vm - resp = self.request('/vms/test-vm/ifaces/%s' % iface['mac'], - '{}', 'DELETE') + 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Create alternate storage @@ -795,33 +869,37 @@ def test_vm_customise_storage(self): 'allocated': 512, 'path': '/tmp', 'type': 'dir'}) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, 'POST') self.assertEquals(201, resp.status) - resp = self.request('/storagepools/alt/activate', req, 'POST') + 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': '/templates/test', - 'storagepool': '/storagepools/alt'}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm', {}, 'GET') + 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('/templates/test').read()) - self.assertEquals(t['storagepool'], '/storagepools/default-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 = '/storagepools/alt/storagevolumes/%s-0.img' % vm_info['uuid'] + 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('/vms/test-vm', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE') self.assertEquals(204, resp.status) # Verify the volume was deleted @@ -832,71 +910,79 @@ def test_scsi_fc_storage(self): req = json.dumps({'name': 'scsi_fc_pool', 'type': 'scsi', 'source': {'adapter_name': 'scsi_host2'}}) - resp = self.request('/storagepools', req, 'POST') + 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('/storagepools/scsi_fc_pool/activate', '{}', - 'POST') + 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': '/storagepools/scsi_fc_pool'} + tmpl_params = { + 'name': 'test_fc_pool', 'cdrom': fake_iso, + 'storagepool': '/plugins/kimchi/storagepools/scsi_fc_pool' + } req = json.dumps(tmpl_params) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(400, resp.status) # Choose SCSI volume to create template - resp = self.request('/storagepools/scsi_fc_pool/storagevolumes') + 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('/templates', req, 'POST') + 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': '/templates/test_fc_pool'}) - resp = self.request('/vms', req, 'POST') + '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('/vms/test-vm/start', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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('/vms/test-vm/poweroff', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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('/templates', req, 'POST') + 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': '/templates/test'}) - task = json.loads(self.request('/vms', req, 'POST').read()) + 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('/vms/test-vm-%i' % i, {}, 'GET') + resp = self.request('/plugins/kimchi/vms/test-vm-%i' % i, {}, + 'GET') self.assertEquals(resp.status, 200) - count = len(json.loads(self.request('/vms').read())) + 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('/vms', req, 'POST') + resp = self.request('/plugins/kimchi/vms', req, 'POST') self.assertEquals(400, resp.status) resp = json.loads(resp.read()) self.assertIn(u"KCHVM0016E:", resp['reason']) @@ -904,32 +990,38 @@ def test_create_vm_without_template(self): def test_create_vm_with_bad_template_uri(self): req = json.dumps({'name': 'vm-bad-template', 'template': '/mytemplate'}) - resp = self.request('/vms', req, 'POST') + 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('/storagepools/default-pool/storagevolumes').read()) + 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) - req = json.dumps({'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + 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('/storagepools/default-pool/storagevolumes').read()) + self.request( + '/plugins/kimchi/storagepools/default-pool/storagevolumes' + ).read() + ) self.assertEquals(1, len(resp)) def _create_pool(self, name): @@ -938,24 +1030,26 @@ def _create_pool(self, name): 'allocated': 5120, 'path': '/var/lib/libvirt/images/', 'type': 'dir'}) - resp = self.request('/storagepools', req, 'POST') + resp = self.request('/plugins/kimchi/storagepools', req, 'POST') self.assertEquals(201, resp.status) # Verify the storage pool - storagepool = json.loads(self.request('/storagepools/%s' + 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('/storagepools/%s' % name, '{}', 'DELETE') + 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('/storagepools/pool-3/activate', '{}', 'POST') + self.request('/plugins/kimchi/storagepools/pool-3/activate', '{}', + 'POST') params = {'name': 'fedora.iso', 'capacity': 1073741824, # 1 GiB 'type': 'file', @@ -963,8 +1057,11 @@ def test_iso_scan_shallow(self): task_info = model.storagevolumes_create('pool-3', params) wait_task(self._task_lookup, task_info['id']) - storagevolume = json.loads(self.request( - '/storagepools/kimchi_isos/storagevolumes/').read())[0] + 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', @@ -982,83 +1079,91 @@ def test_iso_scan_shallow(self): 'cdrom': storagevolume['path'], 'os_distro': storagevolume['os_distro'], 'os_version': storagevolume['os_version']}) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Verify the template - t = json.loads(self.request('/templates/test').read()) + 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('/storagepools/kimchi_isos/storagevolumes' - '/deactivate', '{}', 'POST') + resp = self.request( + '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes' + '/deactivate', '{}', 'POST' + ) self.assertEquals(405, resp.status) - resp = self.request('/storagepools/kimchi_isos/storagevolumes', - '{}', 'DELETE') + resp = self.request( + '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes', + '{}', 'DELETE' + ) self.assertEquals(405, resp.status) # Delete the template - resp = self.request('/templates/%s' % t['name'], '{}', 'DELETE') + resp = self.request('/plugins/kimchi/templates/%s' % t['name'], '{}', + 'DELETE') self.assertEquals(204, resp.status) - resp = self.request('/storagepools/pool-3/deactivate', '{}', 'POST') + 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('/templates', req, 'POST') - req = json.dumps({'name': 'test-vm', 'template': '/templates/test'}) - resp = self.request('/vms', req, 'POST') + 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('/vms/test-vm/screenshot') + resp = self.request('/plugins/kimchi/vms/test-vm/screenshot') self.assertEquals(404, resp.status) # Test screenshot for running vm - resp = self.request('/vms/test-vm/start', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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('/vms/test-vm/screenshot') + 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('/vms/test-vm/screenshot') + resp = self.request('/plugins/kimchi/vms/test-vm/screenshot') lastMod2 = resp.getheader('last-modified') self.assertEquals(lastMod2, lastMod1) - resp = self.request('/vms/test-vm/screenshot', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/vms/test-vm/screenshot', '{}', + 'DELETE') self.assertEquals(405, resp.status) # No screenshot after stopped the VM - self.request('/vms/test-vm/poweroff', '{}', 'POST') - resp = self.request('/vms/test-vm/screenshot') + 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('/vms/test-vm/start', '{}', 'POST') - vm = json.loads(self.request('/vms/test-vm').read()) + 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('/vms/test-vm', '{}', 'DELETE') + 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('/interfaces').read() + resp = self.request('/plugins/kimchi/interfaces').read() self.assertIn('name', resp) interfaces = json.loads(resp) keys = ['name', 'type', 'ipaddr', 'netmask', 'status'] @@ -1066,39 +1171,50 @@ def test_interfaces(self): self.assertEquals(sorted(keys), sorted(interface.keys())) def _task_lookup(self, taskid): - return json.loads(self.request('/tasks/%s' % taskid).read()) + return json.loads( + self.request('/plugins/kimchi/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) + id1 = add_task('/plugins/kimchi/tasks/1', self._async_op, + model.objstore) + id2 = add_task('/plugins/kimchi/tasks/2', self._except_op, + model.objstore) + id3 = add_task('/plugins/kimchi/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()) + tasks = json.loads( + self.request('/plugins/kimchi/tasks?%s' % filter_data).read() + ) self.assertEquals(3, len(tasks)) - tasks = json.loads(self.request('/tasks').read()) + tasks = json.loads(self.request('/plugins/kimchi/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()) + foo2 = json.loads( + self.request('/plugins/kimchi/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()) + foo3 = json.loads( + self.request('/plugins/kimchi/tasks/%s' % id3).read() + ) self.assertEquals('in progress', foo3['message']) self.assertEquals('running', foo3['status']) def test_config(self): - resp = self.request('/config').read() + 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('/config/capabilities').read() + resp = self.request('/plugins/kimchi/config/capabilities').read() conf = json.loads(resp) keys = [u'libvirt_stream_protocols', u'qemu_stream', u'qemu_spice', @@ -1108,11 +1224,11 @@ def test_capabilities(self): self.assertEquals(sorted(keys), sorted(conf.keys())) def test_peers(self): - resp = self.request('/peers').read() + resp = self.request('/plugins/kimchi/peers').read() self.assertEquals([], json.loads(resp)) def test_distros(self): - resp = self.request('/config/distros').read() + resp = self.request('/plugins/kimchi/config/distros').read() distros = json.loads(resp) for distro in distros: self.assertIn('name', distro) @@ -1122,7 +1238,8 @@ def test_distros(self): # Test in X86 ident = "Fedora 20" - resp = self.request('/config/distros/%s' % urllib2.quote(ident)).read() + 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) @@ -1136,7 +1253,8 @@ def test_distros(self): # Test in PPC ident = "Fedora 20 (PPC64)" - resp = self.request('/config/distros/%s' % urllib2.quote(ident)).read() + 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) @@ -1149,48 +1267,55 @@ def test_distros(self): self.assertIn('KCHDISTRO0001E', distro.get('reason')) def test_debugreports(self): - resp = request(host, ssl_port, '/debugreports') + resp = request(host, ssl_port, '/plugins/kimchi/debugreports') self.assertEquals(200, resp.status) def _report_delete(self, name): - request(host, ssl_port, '/debugreports/%s' % name, '{}', 'DELETE') + 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, '/debugreports', req, 'POST') + 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, '/debugreports/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) req = json.dumps({'name': 'report2'}) - resp = request(host, ssl_port, '/debugreports/report1', - req, 'PUT') + 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, '/debugreports', req, 'POST') + 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, '/debugreports/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, '/debugreports/report1/content') + resp = request(host, ssl_port, + '/plugins/kimchi/debugreports/report1/content') self.assertEquals(200, resp.status) - resp = request(host, ssl_port, '/debugreports/report1') + 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) @@ -1201,7 +1326,7 @@ def verify_repo(t, res): if field in t.keys(): self.assertEquals(t[field], res[field]) - base_uri = '/host/repositories' + base_uri = '/plugins/kimchi/host/repositories' resp = self.request(base_uri) self.assertEquals(200, resp.status) # Already have one repo in Kimchi's system diff --git a/tests/test_rollbackcontext.py b/plugins/kimchi/tests/test_rollbackcontext.py similarity index 98% rename from tests/test_rollbackcontext.py rename to plugins/kimchi/tests/test_rollbackcontext.py index 1492d33a5..6eac6d0d6 100644 --- a/tests/test_rollbackcontext.py +++ b/plugins/kimchi/tests/test_rollbackcontext.py @@ -19,7 +19,7 @@ import unittest -from kimchi.rollbackcontext import RollbackContext +from wok.rollbackcontext import RollbackContext class FirstError(Exception): diff --git a/tests/test_server.py b/plugins/kimchi/tests/test_server.py similarity index 88% rename from tests/test_server.py rename to plugins/kimchi/tests/test_server.py index a4d31d00c..d7f1af039 100644 --- a/tests/test_server.py +++ b/plugins/kimchi/tests/test_server.py @@ -24,12 +24,14 @@ 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 -from kimchi import mockmodel -from kimchi.control.base import Collection, Resource + test_server = None model = None @@ -132,13 +134,13 @@ def test_404(self): """ A non-existent path should return HTTP:404 """ - url_list = ['/doesnotexist', '/vms/blah'] + 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('/templates/blah', '', 'DELETE') + resp = self.request('/plugins/kimchi/templates/blah', '', 'DELETE') self.assertEquals(404, resp.status) def test_accepts(self): @@ -177,10 +179,10 @@ def test_accepts(self): def test_auth_unprotected(self): hdrs = {'AUTHORIZATION': ''} - uris = ['/js/kimchi.min.js', - '/css/theme-default.min.css', + 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', - '/images/icon-vm.png', '/login.html', '/logout'] @@ -190,9 +192,9 @@ def test_auth_unprotected(self): def test_auth_protected(self): hdrs = {'AUTHORIZATION': ''} - uris = ['/vms', - '/vms/doesnotexist', - '/tasks'] + uris = ['/plugins/kimchi/vms', + '/plugins/kimchi/vms/doesnotexist', + '/plugins/kimchi/tasks'] for uri in uris: resp = self.request(uri, None, 'GET', hdrs) @@ -201,7 +203,7 @@ def test_auth_protected(self): def test_auth_bad_creds(self): # Test HTTPBA hdrs = {'AUTHORIZATION': "Basic " + base64.b64encode("nouser:badpass")} - resp = self.request('/vms', None, 'GET', hdrs) + resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs) self.assertEquals(401, resp.status) # Test REST API @@ -216,7 +218,7 @@ def test_auth_browser_no_httpba(self): hdrs = {"X-Requested-With": "XMLHttpRequest"} # Try our request (Note that request() will add a valid HTTPBA header) - resp = self.request('/vms', None, 'GET', hdrs) + resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs) self.assertEquals(401, resp.status) self.assertEquals(None, resp.getheader('WWW-Authenticate')) @@ -226,7 +228,7 @@ def test_auth_session(self): 'Accept': 'application/json'} # Test we are logged out - resp = self.request('/tasks', None, 'GET', hdrs) + resp = self.request('/plugins/kimchi/tasks', None, 'GET', hdrs) self.assertEquals(401, resp.status) # Execute a login call @@ -246,7 +248,7 @@ def test_auth_session(self): hdrs['Cookie'] = cookie # Test we are logged in with the cookie - resp = self.request('/tasks', None, 'GET', hdrs) + resp = self.request('/plugins/kimchi/tasks', None, 'GET', hdrs) self.assertEquals(200, resp.status) # Execute a logout call @@ -255,7 +257,7 @@ def test_auth_session(self): del hdrs['Cookie'] # Test we are logged out - resp = self.request('/tasks', None, 'GET', hdrs) + resp = self.request('/plugins/kimchi/tasks', None, 'GET', hdrs) self.assertEquals(401, resp.status) def test_get_param(self): @@ -265,22 +267,22 @@ def test_get_param(self): # Create 2 different templates req = json.dumps({'name': 'test-tmpl1', 'cdrom': mockiso}) - self.request('/templates', req, 'POST') + self.request('/plugins/kimchi/templates', req, 'POST') req = json.dumps({'name': 'test-tmpl2', 'cdrom': mockiso}) - self.request('/templates', req, 'POST') + self.request('/plugins/kimchi/templates', req, 'POST') # Remove mock iso os.unlink(mockiso) # Get the templates - resp = self.request('/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('/templates?name=test-tmpl1') + resp = self.request('/plugins/kimchi/templates?name=test-tmpl1') self.assertEquals(200, resp.status) res = json.loads(resp.read()) self.assertEquals(1, len(res)) diff --git a/tests/test_storagepoolxml.py b/plugins/kimchi/tests/test_storagepoolxml.py similarity index 98% rename from tests/test_storagepoolxml.py rename to plugins/kimchi/tests/test_storagepoolxml.py index c508c58fe..7e45cca7e 100644 --- a/tests/test_storagepoolxml.py +++ b/plugins/kimchi/tests/test_storagepoolxml.py @@ -20,7 +20,7 @@ import lxml.etree as ET import unittest -from kimchi.model.libvirtstoragepool import StoragePoolDef +from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef class StoragepoolXMLTests(unittest.TestCase): diff --git a/tests/test_template.py b/plugins/kimchi/tests/test_template.py similarity index 77% rename from tests/test_template.py rename to plugins/kimchi/tests/test_template.py index 48ef2293a..6a1a66387 100644 --- a/tests/test_template.py +++ b/plugins/kimchi/tests/test_template.py @@ -21,12 +21,12 @@ import json import os import unittest - from functools import partial -from kimchi import osinfo -from kimchi.config import READONLY_POOL_TYPE -from kimchi.mockmodel import MockModel +from wok.plugins.kimchi import osinfo +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 @@ -62,29 +62,31 @@ def setUp(self): model.reset() def test_tmpl_lifecycle(self): - resp = self.request('/templates') + 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': '/storagepools/alt'} + 'storagepool': '/plugins/kimchi/storagepools/alt'} req = json.dumps(t) - resp = self.request('/templates', req, 'POST') + 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('/templates', req, 'POST') + 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('/templates/test').read()) + tmpl = json.loads( + self.request('/plugins/kimchi/templates/test').read() + ) self.assertEquals(sorted(tmpl.keys()), sorted(keys)) # Verify if default disk format was configured @@ -92,29 +94,34 @@ def test_tmpl_lifecycle(self): self.assertEquals(tmpl['disks'][0]['format'], default_disk_format) # Clone a template - resp = self.request('/templates/test/clone', '{}', 'POST') + resp = self.request('/plugins/kimchi/templates/test/clone', '{}', + 'POST') self.assertEquals(303, resp.status) # Verify the cloned template - tmpl_cloned = json.loads(self.request('/templates/test-clone1').read()) + 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('/templates/test-clone1', '{}', 'DELETE') + 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('/templates', req, 'POST') + 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'}]} + t = {'name': 'test_img_template', + 'disks': [{'base': '/tmp/mock.img'}]} req = json.dumps(t) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) os.remove('/tmp/mock.img') @@ -122,24 +129,29 @@ def test_tmpl_lifecycle(self): t = {'name': 'test-format', 'cdrom': '/tmp/mock.iso', 'disks': [{'index': 0, 'size': 10, 'format': 'vmdk'}]} req = json.dumps(t) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) - tmpl = json.loads(self.request('/templates/test-format').read()) + 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('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) - tmpl = json.loads(self.request('/templates/test').read()) + tmpl = json.loads( + self.request('/plugins/kimchi/templates/test').read() + ) # Update name new_name = u'kīмсhīTmpl' - new_tmpl_uri = '/templates/%s' % new_name.encode('utf-8') + new_tmpl_uri = '/plugins/kimchi/templates/%s' \ + % new_name.encode('utf-8') req = json.dumps({'name': new_name}) - resp = self.request('/templates/test', req, 'PUT') + 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()) @@ -149,11 +161,11 @@ def test_customized_tmpl(self): self.assertEquals(tmpl, update_tmpl) # Update icon - req = json.dumps({'icon': 'images/icon-fedora.png'}) + 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('images/icon-fedora.png', update_tmpl['icon']) + 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'}) @@ -248,7 +260,7 @@ def test_customized_network(self): # Create a template t = {'name': 'test', 'cdrom': '/tmp/mock.iso'} req = json.dumps(t) - resp = self.request('/templates', req, 'POST') + resp = self.request('/plugins/kimchi/templates', req, 'POST') self.assertEquals(201, resp.status) # Create networks to be used for testing @@ -259,7 +271,9 @@ def test_customized_network(self): # Verify the current system has at least one interface to create a # bridged network - interfaces = json.loads(self.request('/interfaces?type=nic').read()) + 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', @@ -269,25 +283,29 @@ def test_customized_network(self): tmpl_nets = [] for net in networks: - self.request('/networks', json.dumps(net), 'POST') + self.request('/plugins/kimchi/networks', json.dumps(net), 'POST') tmpl_nets.append(net['name']) req = json.dumps({'networks': tmpl_nets}) - resp = self.request('/templates/test', req, 'PUT') + 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('/templates', req, 'POST') + 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('/host/partitions').read()) + 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('/host/devices?_cap=fc_host').read()) + fc_devs = json.loads( + self.request('/plugins/kimchi/host/devices?_cap=fc_host').read() + ) fc_devs = [dev['name'] for dev in fc_devs] poolDefs = [ @@ -305,8 +323,10 @@ def test_customized_storagepool(self): 'source': {'devices': [devs[0]]}}] for pool in poolDefs: - self.request('/storagepools', json.dumps(pool), 'POST') - pool_uri = '/storagepools/%s' % pool['name'].encode('utf-8') + 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 @@ -321,44 +341,49 @@ def test_customized_storagepool(self): req = json.dumps({'storagepool': pool_uri}) if req is not None: - resp = self.request('/templates/test', req, 'PUT') + 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('/networks', json.dumps(net), 'POST') + self.request('/plugins/kimchi/networks', json.dumps(net), 'POST') pool = {'type': 'dir', 'name': 'dir-pool', 'path': '/tmp/dir-pool'} - self.request('/storagepools', json.dumps(pool), 'POST') - pool_uri = '/storagepools/%s' % pool['name'].encode('utf-8') + 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': '/storagepools/dir-pool'} + 'storagepool': '/plugins/kimchi/storagepools/dir-pool'} req = json.dumps(t) - resp = self.request('/templates', req, 'POST') + 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('/networks/nat-network', '{}', 'DELETE') + 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('/templates/test', req, 'PUT') - resp = self.request('/networks/nat-network', '{}', 'DELETE') + 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('/storagepools/dir-pool', '{}', 'DELETE') + resp = self.request('/plugins/kimchi/storagepools/dir-pool', '{}', + 'DELETE') self.assertEquals(400, resp.status) # Verify the template - res = json.loads(self.request('/templates/test').read()) + res = json.loads(self.request('/plugins/kimchi/templates/test').read()) self.assertEquals(res['invalid']['cdrom'], ['/tmp/mock.iso']) diff --git a/tests/test_utils.py b/plugins/kimchi/tests/test_utils.py similarity index 97% rename from tests/test_utils.py rename to plugins/kimchi/tests/test_utils.py index b8ff62119..bcb14e278 100644 --- a/tests/test_utils.py +++ b/plugins/kimchi/tests/test_utils.py @@ -19,8 +19,8 @@ import unittest -from kimchi.exception import InvalidParameter -from kimchi.utils import convert_data_size +from wok.exception import InvalidParameter +from wok.utils import convert_data_size class UtilsTests(unittest.TestCase): diff --git a/tests/test_vmtemplate.py b/plugins/kimchi/tests/test_vmtemplate.py similarity index 96% rename from tests/test_vmtemplate.py rename to plugins/kimchi/tests/test_vmtemplate.py index 0ca9adbd6..0bca215eb 100644 --- a/tests/test_vmtemplate.py +++ b/plugins/kimchi/tests/test_vmtemplate.py @@ -21,10 +21,10 @@ import unittest import uuid +from wok.xmlutils.utils import xpath_get_text -from kimchi.osinfo import get_template_default -from kimchi.vmtemplate import VMTemplate -from kimchi.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): diff --git a/tests/test_yumparser.py b/plugins/kimchi/tests/test_yumparser.py similarity index 93% rename from tests/test_yumparser.py rename to plugins/kimchi/tests/test_yumparser.py index 53a2d8073..be5e95c25 100644 --- a/tests/test_yumparser.py +++ b/plugins/kimchi/tests/test_yumparser.py @@ -21,12 +21,13 @@ import tempfile import unittest -from kimchi.model import model -from kimchi.rollbackcontext import RollbackContext -from kimchi.yumparser import delete_repo_from_file, get_repo_files -from kimchi.yumparser import get_yum_packages_list_update -from kimchi.yumparser import get_yum_repositories, write_repo_to_file -from kimchi.yumparser import YumRepoObject +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 = '' diff --git a/tests/utils.py b/plugins/kimchi/tests/utils.py similarity index 90% rename from tests/utils.py rename to plugins/kimchi/tests/utils.py index 2ffe7765a..f80b14fa2 100644 --- a/tests/utils.py +++ b/plugins/kimchi/tests/utils.py @@ -28,20 +28,20 @@ import socket import ssl import sys -import time 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 -import kimchi.mockmodel -import kimchi.server -from kimchi.config import config, paths -from kimchi.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs -from kimchi.exception import NotFoundError, OperationFailed -from kimchi.utils import kimchi_log _ports = {} @@ -118,7 +118,7 @@ def run_server(host, port, ssl_port, test_mode, cherrypy_port=None, if model is not None: setattr(args, 'model', model) - s = kimchi.server.Server(args) + s = wok.server.Server(args) t = threading.Thread(target=s.start) t.setDaemon(True) t.start() @@ -142,7 +142,7 @@ def _request(conn, path, data, method, headers): headers = {'Content-Type': 'application/json', 'Accept': 'application/json'} if 'AUTHORIZATION' not in headers.keys(): - user, pw = kimchi.mockmodel.fake_user.items()[0] + user, pw = mockmodel.fake_user.items()[0] hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw)) headers['AUTHORIZATION'] = hdr conn.request(method, path, data, headers) @@ -167,8 +167,8 @@ def get_remote_iso_path(): """ host_arch = os.uname()[4] remote_path = '' - with open(os.path.join(paths.conf_dir, 'distros.d', 'fedora.json')) \ - as fedora_isos: + 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: @@ -203,7 +203,7 @@ def get_user(self): @staticmethod def authenticate(username, password, service="passwd"): try: - return kimchi.mockmodel.fake_user[username] == password + return mockmodel.fake_user[username] == password except KeyError, e: raise OperationFailed("KCHAUTH0001E", {'username': 'username', 'code': e.message}) @@ -227,13 +227,13 @@ def wait_task(task_lookup, taskid, timeout=10): for i in range(0, timeout): task_info = task_lookup(taskid) if task_info['status'] == "running": - kimchi_log.info("Waiting task %s, message: %s", - taskid, task_info['message']) + wok_log.info("Waiting task %s, message: %s", + taskid, task_info['message']) time.sleep(1) else: return - kimchi_log.error("Timeout while process long-run task, " - "try to increase timeout value.") + 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 @@ -254,7 +254,7 @@ def rollback_wrapper(func, resource, *args): # requests lib take care of encode part, so use this lib instead def fake_auth_header(): headers = {'Accept': 'application/json'} - user, pw = kimchi.mockmodel.fake_user.items()[0] + user, pw = mockmodel.fake_user.items()[0] hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw)) headers['AUTHORIZATION'] = hdr return headers diff --git a/config/Makefile.am b/plugins/kimchi/ui/Makefile.am similarity index 86% rename from config/Makefile.am rename to plugins/kimchi/ui/Makefile.am index 208d3e3c9..21fe703a2 100644 --- a/config/Makefile.am +++ b/plugins/kimchi/ui/Makefile.am @@ -15,4 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -SUBDIRS = ui +SUBDIRS = config css images js pages spice-html5 + +uidir = $(datadir)/wok/plugins/kimchi/ui diff --git a/config/ui/Makefile.am b/plugins/kimchi/ui/config/Makefile.am similarity index 90% rename from config/ui/Makefile.am rename to plugins/kimchi/ui/config/Makefile.am index 32b74e356..e3b3d194d 100644 --- a/config/ui/Makefile.am +++ b/plugins/kimchi/ui/config/Makefile.am @@ -15,8 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -xmldir = $(datadir)/kimchi/config/ui +xmldir = $(datadir)/wok/plugins/kimchi/ui/config dist_xml_DATA = \ - tabs.xml \ + tab-ext.xml \ $(NULL) diff --git a/config/ui/tabs.xml b/plugins/kimchi/ui/config/tab-ext.xml similarity index 73% rename from config/ui/tabs.xml rename to plugins/kimchi/ui/config/tab-ext.xml index f79684cf9..ee88c88fa 100644 --- a/config/ui/tabs.xml +++ b/plugins/kimchi/ui/config/tab-ext.xml @@ -1,38 +1,38 @@ - + Host - tabs/host.html + plugins/kimchi/host.html Guests - tabs/guests.html + plugins/kimchi/guests.html Templates - tabs/templates.html + plugins/kimchi/templates.html Storage - tabs/storage.html + plugins/kimchi/storage.html Network - tabs/network.html + plugins/kimchi/network.html - + diff --git a/plugins/kimchi/ui/css/Makefile.am b/plugins/kimchi/ui/css/Makefile.am new file mode 100644 index 000000000..5071d2929 --- /dev/null +++ b/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/ui/css/theme-default/guest-edit.css b/plugins/kimchi/ui/css/theme-default/guest-edit.css similarity index 97% rename from ui/css/theme-default/guest-edit.css rename to plugins/kimchi/ui/css/theme-default/guest-edit.css index cf71b7849..b66115911 100644 --- a/ui/css/theme-default/guest-edit.css +++ b/plugins/kimchi/ui/css/theme-default/guest-edit.css @@ -134,7 +134,7 @@ } .guest-edit-snapshot .icon { - background: url('../../images/theme-default/kimchi-loading15x15.gif') no-repeat; + background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat; display: block; width: 16px; height: 16px; @@ -256,12 +256,12 @@ } .guest-edit-permission .pam .body .item .user-icon { - background: url('/images/theme-default/user.png') no-repeat scroll; + 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: url('../images/theme-default/group.png') no-repeat scroll; background-size: 15px 15px; } diff --git a/ui/css/theme-default/guest-storage-add.css b/plugins/kimchi/ui/css/theme-default/guest-storage-add.css similarity index 100% rename from ui/css/theme-default/guest-storage-add.css rename to plugins/kimchi/ui/css/theme-default/guest-storage-add.css diff --git a/ui/css/theme-default/host.css b/plugins/kimchi/ui/css/theme-default/host.css similarity index 97% rename from ui/css/theme-default/host.css rename to plugins/kimchi/ui/css/theme-default/host.css index 9e9cb010c..a0cccb133 100644 --- a/ui/css/theme-default/host.css +++ b/plugins/kimchi/ui/css/theme-default/host.css @@ -33,7 +33,7 @@ } .host-panel .logo { - background: url("../images/icon-vm.png") no-repeat left top; + background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top; height: 128px; width: 128px; } @@ -220,7 +220,7 @@ } #id-debug-img { - background: url(../../images/theme-default/kimchi-loading15x15.gif) 12px + background: url(../images/theme-default/kimchi-loading15x15.gif) 12px center no-repeat; padding-left: 23px; } diff --git a/plugins/kimchi/ui/css/theme-default/icon.css b/plugins/kimchi/ui/css/theme-default/icon.css new file mode 100644 index 000000000..f82d45d6a --- /dev/null +++ b/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/ui/css/theme-default/list.css b/plugins/kimchi/ui/css/theme-default/list.css similarity index 98% rename from ui/css/theme-default/list.css rename to plugins/kimchi/ui/css/theme-default/list.css index 718c85518..8c78623b2 100644 --- a/ui/css/theme-default/list.css +++ b/plugins/kimchi/ui/css/theme-default/list.css @@ -312,7 +312,7 @@ } .guest-pending .icon { - background: url('../../images/theme-default/kimchi-loading15x15.gif') no-repeat; + background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat; display: inline-block; width: 20px; height: 20px; diff --git a/ui/css/theme-default/network.css b/plugins/kimchi/ui/css/theme-default/network.css similarity index 98% rename from ui/css/theme-default/network.css rename to plugins/kimchi/ui/css/theme-default/network.css index e5a8e476e..fc8a24f51 100644 --- a/ui/css/theme-default/network.css +++ b/plugins/kimchi/ui/css/theme-default/network.css @@ -92,7 +92,7 @@ } .network .list .nw-loading { - background: #c0c0c0 url(../../images/theme-default/loading.gif) + background: #c0c0c0 url(../images/theme-default/loading.gif) center no-repeat; } @@ -264,4 +264,4 @@ #networkConfig { padding-left: 30px; -} \ No newline at end of file +} diff --git a/ui/css/theme-default/report-add.css b/plugins/kimchi/ui/css/theme-default/report-add.css similarity index 100% rename from ui/css/theme-default/report-add.css rename to plugins/kimchi/ui/css/theme-default/report-add.css diff --git a/ui/css/theme-default/report-rename.css b/plugins/kimchi/ui/css/theme-default/report-rename.css similarity index 99% rename from ui/css/theme-default/report-rename.css rename to plugins/kimchi/ui/css/theme-default/report-rename.css index 84bdf1705..2fb2698da 100644 --- a/ui/css/theme-default/report-rename.css +++ b/plugins/kimchi/ui/css/theme-default/report-rename.css @@ -36,4 +36,4 @@ color: #999999; font-weight: lighter; font-family: 'Helvetica Neue', Helvetica, Arial; -} \ No newline at end of file +} diff --git a/ui/css/theme-default/repository-add.css b/plugins/kimchi/ui/css/theme-default/repository-add.css similarity index 100% rename from ui/css/theme-default/repository-add.css rename to plugins/kimchi/ui/css/theme-default/repository-add.css diff --git a/ui/css/theme-default/repository-edit.css b/plugins/kimchi/ui/css/theme-default/repository-edit.css similarity index 100% rename from ui/css/theme-default/repository-edit.css rename to plugins/kimchi/ui/css/theme-default/repository-edit.css diff --git a/ui/css/theme-default/storage.css b/plugins/kimchi/ui/css/theme-default/storage.css similarity index 98% rename from ui/css/theme-default/storage.css rename to plugins/kimchi/ui/css/theme-default/storage.css index 771cc7f05..88447b56a 100644 --- a/ui/css/theme-default/storage.css +++ b/plugins/kimchi/ui/css/theme-default/storage.css @@ -215,10 +215,6 @@ border: 1px solid rgb(204, 204, 204); } -.hide-content { - display: none!important; -} - .volumeslist { padding: 7px; max-height: 272px; @@ -489,7 +485,7 @@ #pool-loading { margin: 10px 15px; - background: #C0C0C0 url(../../images/theme-default/loading.gif) 7px + background: #C0C0C0 url(../images/theme-default/loading.gif) 7px center no-repeat; padding: 0 20px 0 26px; } diff --git a/ui/css/theme-default/storagepool-add-volume.css b/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css similarity index 100% rename from ui/css/theme-default/storagepool-add-volume.css rename to plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css diff --git a/ui/css/theme-default/template-edit.css b/plugins/kimchi/ui/css/theme-default/template-edit.css similarity index 100% rename from ui/css/theme-default/template-edit.css rename to plugins/kimchi/ui/css/theme-default/template-edit.css diff --git a/ui/css/theme-default/template.css b/plugins/kimchi/ui/css/theme-default/template.css similarity index 100% rename from ui/css/theme-default/template.css rename to plugins/kimchi/ui/css/theme-default/template.css diff --git a/ui/css/theme-default/template_add.css b/plugins/kimchi/ui/css/theme-default/template_add.css similarity index 96% rename from ui/css/theme-default/template_add.css rename to plugins/kimchi/ui/css/theme-default/template_add.css index 668c78557..f1e28c50e 100644 --- a/ui/css/theme-default/template_add.css +++ b/plugins/kimchi/ui/css/theme-default/template_add.css @@ -175,7 +175,7 @@ margin: 0 5px 0 0; border: 1px solid #CCCCCC; border-radius: 8px; - background: url(../../images/icon-vm.png) center center no-repeat; + background: url(../images/icon-vm.png) center center no-repeat; background-size: 58px; } @@ -284,13 +284,13 @@ #iso-search-loading { margin: 10px 15px; - background: #C0C0C0 url(../../images/theme-default/loading.gif) 7px + 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 + background: #C0C0C0 url(../images/theme-default/loading.gif) 7px center no-repeat; padding: 0 20px 0 26px; } diff --git a/ui/css/theme-default/template_list.css b/plugins/kimchi/ui/css/theme-default/template_list.css similarity index 100% rename from ui/css/theme-default/template_list.css rename to plugins/kimchi/ui/css/theme-default/template_list.css diff --git a/plugins/kimchi/ui/images/Makefile.am b/plugins/kimchi/ui/images/Makefile.am new file mode 100644 index 000000000..ca3ee6e8d --- /dev/null +++ b/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/ui/images/icon-centos.png b/plugins/kimchi/ui/images/icon-centos.png similarity index 100% rename from ui/images/icon-centos.png rename to plugins/kimchi/ui/images/icon-centos.png diff --git a/ui/images/icon-debian.png b/plugins/kimchi/ui/images/icon-debian.png similarity index 100% rename from ui/images/icon-debian.png rename to plugins/kimchi/ui/images/icon-debian.png diff --git a/ui/images/icon-fedora.png b/plugins/kimchi/ui/images/icon-fedora.png similarity index 100% rename from ui/images/icon-fedora.png rename to plugins/kimchi/ui/images/icon-fedora.png diff --git a/ui/images/icon-gentoo.png b/plugins/kimchi/ui/images/icon-gentoo.png similarity index 100% rename from ui/images/icon-gentoo.png rename to plugins/kimchi/ui/images/icon-gentoo.png diff --git a/ui/images/icon-opensuse.png b/plugins/kimchi/ui/images/icon-opensuse.png similarity index 100% rename from ui/images/icon-opensuse.png rename to plugins/kimchi/ui/images/icon-opensuse.png diff --git a/ui/images/icon-ubuntu.png b/plugins/kimchi/ui/images/icon-ubuntu.png similarity index 100% rename from ui/images/icon-ubuntu.png rename to plugins/kimchi/ui/images/icon-ubuntu.png diff --git a/ui/images/icon-vm.png b/plugins/kimchi/ui/images/icon-vm.png similarity index 100% rename from ui/images/icon-vm.png rename to plugins/kimchi/ui/images/icon-vm.png diff --git a/ui/pages/tabs/Makefile.am b/plugins/kimchi/ui/images/theme-default/Makefile.am similarity index 85% rename from ui/pages/tabs/Makefile.am rename to plugins/kimchi/ui/images/theme-default/Makefile.am index a29df7eb0..7e11d757c 100644 --- a/ui/pages/tabs/Makefile.am +++ b/plugins/kimchi/ui/images/theme-default/Makefile.am @@ -15,6 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -tabshtmldir = $(datadir)/kimchi/ui/pages/tabs +imagedir = $(datadir)/wok/plugins/kimchi/ui/images/theme-default -dist_tabshtml_DATA = $(wildcard *.html.tmpl) $(NULL) +dist_image_DATA = *.png *.gif diff --git a/ui/images/theme-default/ac22_pause.png b/plugins/kimchi/ui/images/theme-default/ac22_pause.png similarity index 100% rename from ui/images/theme-default/ac22_pause.png rename to plugins/kimchi/ui/images/theme-default/ac22_pause.png diff --git a/ui/images/theme-default/ac22_pause_grey.png b/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png similarity index 100% rename from ui/images/theme-default/ac22_pause_grey.png rename to plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png diff --git a/ui/images/theme-default/ac24_resume.png b/plugins/kimchi/ui/images/theme-default/ac24_resume.png similarity index 100% rename from ui/images/theme-default/ac24_resume.png rename to plugins/kimchi/ui/images/theme-default/ac24_resume.png diff --git a/ui/images/theme-default/ac24_resume_grey.png b/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png similarity index 100% rename from ui/images/theme-default/ac24_resume_grey.png rename to plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down-black.png b/plugins/kimchi/ui/images/theme-default/arrow-down-black.png new file mode 100644 index 0000000000000000000000000000000000000000..2c05f00498232213a081497051c94d16537daab8 GIT binary patch literal 2942 zcmV-^3xV{BP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?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(?@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_-kiKB_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+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0001~NklMQ2qgPBk{XD$FDVh-E^lOy|E;2qe6N<`dd=IYe8TI+0p1?Vz!djeVjuLVFI zt6i=2>Iiylaa~&20iVF-U$~(+;0bss?Ku1Y@F9wb4}QKwE$URgR{P9UU8)c2y*e6p ohvWRhz!A$d6~#>G7g3=>Q#G^&cL#z*Q$%}FLnMWF=;0ky z&|yo<#f2xjw6^sJL}L+>rbk!=xqXGrqjf!~62S@ZUy&d_HeP zq|VMxrlzL$3=aS4p8z=mPEn&wyM2ed+_?sd}|g zDEv`2GBVPo-j0Z3L|jmxbYwD_l6og14yzZ{&P*orF`Lb $@ + +CLEANFILES = kimchi.min.js diff --git a/ui/js/src/kimchi.api.js b/plugins/kimchi/ui/js/src/kimchi.api.js similarity index 72% rename from ui/js/src/kimchi.api.js rename to plugins/kimchi/ui/js/src/kimchi.api.js index 44f58d187..dc1596d03 100644 --- a/ui/js/src/kimchi.api.js +++ b/plugins/kimchi/ui/js/src/kimchi.api.js @@ -17,35 +17,10 @@ */ var kimchi = { - url : "../../../", - widget: {}, trackingTasks: [], - /** - * A wrapper of jQuery.ajax function to allow custom bindings. - * - * @param settings an extended object to jQuery Ajax settings object - * with some extra properties (see below) - * - * resend: if the XHR has failed due to 401, the XHR can be resent - * after user being authenticated successfully by setting resend - * to true: settings = {resend: true}. It's useful for switching - * pages (Guests, Templates, etc.). - * e.g., the user wants to list guests by clicking Guests tab, - * but he is told not authorized and a login window will pop up. - * After login, the Ajax request for /vms will be resent without - * user clicking the tab again. - * Default to false. - */ - requestJSON : function(settings) { - settings['originalError'] = settings['error']; - settings['error'] = null; - settings['kimchi'] = true; - return $.ajax(settings); - }, - /** * * Get host capabilities @@ -53,8 +28,8 @@ var kimchi = { */ getCapabilities : function(suc, err, done) { done = typeof done !== 'undefined' ? done: function(){}; - kimchi.requestJSON({ - url : "config/capabilities", + wok.requestJSON({ + url : "plugins/kimchi/config/capabilities", type : "GET", contentType : "application/json", dataType : "json", @@ -68,8 +43,8 @@ var kimchi = { * Get the i18 strings. */ getI18n: function(suc, err, url, sync) { - kimchi.requestJSON({ - url : url ? url : 'i18n.json', + wok.requestJSON({ + url : url ? url : 'plugins/kimchi/i18n.json', type : 'GET', resend: true, dataType : 'json', @@ -83,8 +58,8 @@ var kimchi = { * Get the host static information. */ getHost: function(suc, err) { - kimchi.requestJSON({ - url : 'host', + wok.requestJSON({ + url : 'plugins/kimchi/host', type : 'GET', resend: true, contentType : 'application/json', @@ -98,11 +73,11 @@ var kimchi = { * Get the dynamic host stats (usually used for monitoring). */ getHostStats : function(suc, err) { - kimchi.requestJSON({ - url : 'host/stats', + wok.requestJSON({ + url : 'plugins/kimchi/host/stats', type : 'GET', contentType : 'application/json', - headers: {'Kimchi-Robot': 'kimchi-robot'}, + headers: {'Wok-Robot': 'wok-robot'}, dataType : 'json', success : suc, error: err @@ -113,12 +88,12 @@ var kimchi = { * Get the historic host stats. */ getHostStatsHistory : function(suc, err) { - kimchi.requestJSON({ - url : 'host/stats/history', + wok.requestJSON({ + url : 'plugins/kimchi/host/stats/history', type : 'GET', resend: true, contentType : 'application/json', - headers: {'Kimchi-Robot': 'kimchi-robot'}, + headers: {'Wok-Robot': 'wok-robot'}, dataType : 'json', success : suc, error: err @@ -137,8 +112,8 @@ var kimchi = { * suc: callback if succeed err: callback if failed */ createVM : function(settings, suc, err) { - kimchi.requestJSON({ - url : "vms", + wok.requestJSON({ + url : "plugins/kimchi/vms", type : "POST", contentType : "application/json", data : JSON.stringify(settings), @@ -153,8 +128,8 @@ var kimchi = { * if failed */ createTemplate : function(settings, suc, err) { - kimchi.requestJSON({ - url : "templates", + wok.requestJSON({ + url : "plugins/kimchi/templates", type : "POST", contentType : "application/json", data : JSON.stringify(settings), @@ -165,8 +140,8 @@ var kimchi = { }, deleteTemplate : function(tem, suc, err) { - kimchi.requestJSON({ - url : 'templates/' + encodeURIComponent(tem), + wok.requestJSON({ + url : 'plugins/kimchi/templates/' + encodeURIComponent(tem), type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -176,8 +151,8 @@ var kimchi = { }, cloneTemplate : function(tem, suc, err) { - kimchi.requestJSON({ - url : 'templates/' + encodeURIComponent(tem) + "/clone", + wok.requestJSON({ + url : 'plugins/kimchi/templates/' + encodeURIComponent(tem) + "/clone", type : 'POST', contentType : 'application/json', dataType : 'json', @@ -187,8 +162,8 @@ var kimchi = { }, listTemplates : function(suc, err) { - kimchi.requestJSON({ - url : 'templates', + wok.requestJSON({ + url : 'plugins/kimchi/templates', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -201,8 +176,8 @@ var kimchi = { * Retrieve the information of a template by the given name. */ retrieveTemplate : function(templateName, suc, err) { - kimchi.requestJSON({ - url : "templates/" + encodeURIComponent(templateName), + wok.requestJSON({ + url : 'plugins/kimchi/templates/' + encodeURIComponent(templateName), type : 'GET', contentType : 'application/json', dataType : 'json' @@ -216,7 +191,7 @@ var kimchi = { */ updateTemplate : function(name, settings, suc, err) { $.ajax({ - url : "templates/" + encodeURIComponent(name), + url : 'plugins/kimchi/templates/' + encodeURIComponent(name), type : 'PUT', contentType : 'application/json', data : JSON.stringify(settings), @@ -231,8 +206,8 @@ var kimchi = { * The unit is MBytes suc: callback if succeed err: callback if failed */ createStoragePool : function(settings, suc, err) { - kimchi.requestJSON({ - url : 'storagepools', + wok.requestJSON({ + url : 'plugins/kimchi/storagepools', type : 'POST', contentType : 'application/json', data : JSON.stringify(settings), @@ -242,19 +217,19 @@ var kimchi = { updateStoragePool : function(name, content, suc, err) { $.ajax({ - url : "storagepools/" + encodeURIComponent(name), + url : "plugins/kimchi/storagepools/" + encodeURIComponent(name), type : 'PUT', contentType : 'application/json', dataType : 'json', data : JSON.stringify(content) }).done(suc).fail(err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); }); }, startVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/start', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/start', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -264,8 +239,8 @@ var kimchi = { }, poweroffVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/poweroff', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/poweroff', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -275,8 +250,8 @@ var kimchi = { }, shutdownVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/shutdown', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/shutdown', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -286,8 +261,8 @@ var kimchi = { }, resetVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/reset', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/reset', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -297,8 +272,8 @@ var kimchi = { }, suspendVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/suspend', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/suspend', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -308,8 +283,8 @@ var kimchi = { }, resumeVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + '/resume', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/resume', type : 'POST', contentType : 'application/json', dataType : 'json', @@ -327,7 +302,7 @@ var kimchi = { */ retrieveVM : function(vm, suc, err) { $.ajax({ - url : 'vms/' + encodeURIComponent(vm), + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm), type : 'GET', contentType : 'application/json', dataType : 'json', @@ -341,7 +316,7 @@ var kimchi = { */ updateVM : function(name, settings, suc, err) { $.ajax({ - url : "vms/" + encodeURIComponent(name), + url : "plugins/kimchi/vms/" + encodeURIComponent(name), type : 'PUT', contentType : 'application/json', data : JSON.stringify(settings), @@ -352,8 +327,8 @@ var kimchi = { }, deleteVM : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm), + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm), type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -363,19 +338,20 @@ var kimchi = { }, vncToVM : function(vm) { - kimchi.requestJSON({ - url : 'config', + wok.requestJSON({ + url : 'plugins/kimchi/config', type : 'GET', dataType : 'json' }).done(function(data, textStatus, xhr) { proxy_port = data['display_proxy_port']; - kimchi.requestJSON({ - url : "vms/" + encodeURIComponent(vm) + "/connect", + 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=" + encodeURIComponent("novnc/vnc_auto.html"); + url += "/console.html?url="; + url += encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html"); url += "&port=" + proxy_port; /* * From python documentation base64.urlsafe_b64encode(s) @@ -384,31 +360,31 @@ var kimchi = { * 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=" + kimchi.urlSafeB64Encode(vm).replace(/=*$/g, ""); - url += "&kimchi=" + location.port; + url += "&path=?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, ""); + url += "&wok=" + location.port; url += '&encrypt=1'; window.open(url); }); }).error(function() { - kimchi.message.error.code('KCHAPI6002E'); + wok.message.error.code('KCHAPI6002E'); }); }, spiceToVM : function(vm) { - kimchi.requestJSON({ - url : 'config', + wok.requestJSON({ + url : 'plugins/kimchi/config', type : 'GET', dataType : 'json' }).done(function(data, textStatus, xhr) { proxy_port = data['display_proxy_port']; - kimchi.requestJSON({ - url : "vms/" + encodeURIComponent(vm) + "/connect", + 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=spice_auto.html&port=" + proxy_port; - url += "&listen=" + location.hostname; + 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 @@ -416,22 +392,22 @@ var kimchi = { * contain = which is not safe in a URL query component. * So remove it when needed as base64 can work well without it. * */ - url += "&token=" + kimchi.urlSafeB64Encode(vm).replace(/=*$/g, ""); - url += "&kimchi=" + location.port; + url += "&token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, ""); + url += "&wok=" + location.port; url += '&encrypt=1'; window.open(url); }); }).error(function() { - kimchi.message.error.code('KCHAPI6002E'); + wok.message.error.code('KCHAPI6002E'); }); }, listVMs : function(suc, err) { - kimchi.requestJSON({ - url : 'vms', + wok.requestJSON({ + url : 'plugins/kimchi/vms', type : 'GET', contentType : 'application/json', - headers: {'Kimchi-Robot': 'kimchi-robot'}, + headers: {'Wok-Robot': 'wok-robot'}, dataType : 'json', resend: true, success : suc, @@ -440,8 +416,8 @@ var kimchi = { }, listTemplates : function(suc, err) { - kimchi.requestJSON({ - url : 'templates', + wok.requestJSON({ + url : 'plugins/kimchi/templates', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -452,8 +428,8 @@ var kimchi = { }, listStoragePools : function(suc, err) { - kimchi.requestJSON({ - url : 'storagepools', + wok.requestJSON({ + url : 'plugins/kimchi/storagepools', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -465,7 +441,7 @@ var kimchi = { listStorageVolumes : function(poolName, suc, err) { $.ajax({ - url : 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes', + url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -475,8 +451,8 @@ var kimchi = { }, listIsos : function(suc, err) { - kimchi.requestJSON({ - url : 'storagepools/kimchi_isos/storagevolumes', + wok.requestJSON({ + url : 'plugins/kimchi/storagepools/kimchi_isos/storagevolumes', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -486,8 +462,8 @@ var kimchi = { }, listDistros : function(suc, err) { - kimchi.requestJSON({ - url : 'config/distros', + wok.requestJSON({ + url : 'plugins/kimchi/config/distros', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -548,8 +524,8 @@ var kimchi = { }, getTask : function(taskId, suc, err) { - kimchi.requestJSON({ - url : 'tasks/' + encodeURIComponent(taskId), + wok.requestJSON({ + url : 'plugins/kimchi/tasks/' + encodeURIComponent(taskId), type : 'GET', contentType : 'application/json', dataType : 'json', @@ -559,8 +535,8 @@ var kimchi = { }, getTasksByFilter : function(filter, suc, err, sync) { - kimchi.requestJSON({ - url : 'tasks?' + filter, + wok.requestJSON({ + url : 'plugins/kimchi/tasks?' + filter, type : 'GET', contentType : 'application/json', dataType : 'json', @@ -570,28 +546,9 @@ var kimchi = { }); }, - login : function(settings, suc, err) { - $.ajax({ - url : "login", - type : "POST", - contentType : "application/json", - data : JSON.stringify(settings), - dataType : "json" - }).done(suc).fail(err); - }, - - logout : function(suc, err) { - kimchi.requestJSON({ - url : 'logout', - type : 'POST', - contentType : "application/json", - dataType : "json" - }).done(suc).fail(err); - }, - deleteStoragePool : function(poolName, suc, err) { $.ajax({ - url : 'storagepools/' + encodeURIComponent(poolName), + url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName), type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -603,7 +560,7 @@ var kimchi = { changePoolState : function(poolName, state, suc, err) { if (state === 'activate' || state === 'deactivate') $.ajax({ - url : 'storagepools/' + encodeURIComponent(poolName) + '/' + state, + url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/' + state, type : 'POST', contentType : 'application/json', dataType : 'json', @@ -612,91 +569,78 @@ var kimchi = { }); }, - listPlugins : function(suc, err, sync) { - kimchi.requestJSON({ - url : 'plugins', - type : 'GET', - contentType : 'application/json', - dataType : 'json', - resend: true, - async : !sync, - success : suc, - error : err - }); - }, - listNetworks : function(suc, err) { - kimchi.requestJSON({ - url : 'networks', + wok.requestJSON({ + url : 'plugins/kimchi/networks', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, toggleNetwork : function(name, on, suc, err) { var action = on ? "activate" : "deactivate"; - kimchi.requestJSON({ - url : 'networks/' + encodeURIComponent(name) + '/' + action, + wok.requestJSON({ + url : 'plugins/kimchi/networks/' + encodeURIComponent(name) + '/' + action, type : 'POST', contentType : 'application/json', dataType : 'json', success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, createNetwork : function(network, suc, err) { - kimchi.requestJSON({ - url : 'networks', + wok.requestJSON({ + url : 'plugins/kimchi/networks', type : 'POST', contentType : 'application/json', dataType : 'json', data : JSON.stringify(network), success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getInterfaces : function(suc, err) { - kimchi.requestJSON({ - url : 'interfaces', + wok.requestJSON({ + url : 'plugins/kimchi/interfaces', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, deleteNetwork : function(name, suc, err) { - kimchi.requestJSON({ - url : 'networks/' + encodeURIComponent(name), + wok.requestJSON({ + url : 'plugins/kimchi/networks/' + encodeURIComponent(name), type : 'DELETE', contentType : 'application/json', dataType : 'json', success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, listReports : function(suc, err) { - kimchi.requestJSON({ - url : 'debugreports', + wok.requestJSON({ + url : 'plugins/kimchi/debugreports', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -738,8 +682,8 @@ var kimchi = { kimchi.trackTask(taskID, suc, err, progress); }; - kimchi.requestJSON({ - url : 'debugreports', + wok.requestJSON({ + url : 'plugins/kimchi/debugreports', type : "POST", contentType : "application/json", data : JSON.stringify(settings), @@ -751,7 +695,7 @@ var kimchi = { renameReport : function(name, settings, suc, err) { $.ajax({ - url : "debugreports/" + encodeURIComponent(name), + url : "plugins/kimchi/debugreports/" + encodeURIComponent(name), type : 'PUT', contentType : 'application/json', data : JSON.stringify(settings), @@ -763,8 +707,8 @@ var kimchi = { deleteReport: function(settings, suc, err) { var reportName = encodeURIComponent(settings['name']); - kimchi.requestJSON({ - url : 'debugreports/' + reportName, + wok.requestJSON({ + url : 'plugins/kimchi/debugreports/' + reportName, type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -779,8 +723,8 @@ var kimchi = { shutdown: function(settings, suc, err) { var reboot = settings && settings['reboot'] === true; - var url = 'host/' + (reboot ? 'reboot' : 'shutdown'); - kimchi.requestJSON({ + var url = 'plugins/kimchi/host/' + (reboot ? 'reboot' : 'shutdown'); + wok.requestJSON({ url : url, type : 'POST', contentType : 'application/json', @@ -791,8 +735,8 @@ var kimchi = { }, listHostPartitions : function(suc, err) { - kimchi.requestJSON({ - url : 'host/partitions', + wok.requestJSON({ + url : 'plugins/kimchi/host/partitions', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -802,22 +746,22 @@ var kimchi = { }, getStorageServers: function(type, suc, err) { - var url = 'storageservers?_target_type=' + type; - kimchi.requestJSON({ + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getStorageTargets: function(server,type, suc, err) { - var url = 'storageservers/' + server + '/storagetargets?_target_type=' + type; - kimchi.requestJSON({ + var url = 'plugins/kimchi/storageservers/' + server + '/storagetargets?_target_type=' + type; + wok.requestJSON({ url : url, type : 'GET', contentType : 'application/json', @@ -829,8 +773,8 @@ var kimchi = { }, getStoragePool: function(poolName, suc, err) { - var url = kimchi.url + 'storagepools/' + encodeURIComponent(poolName); - kimchi.requestJSON({ + var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName); + wok.requestJSON({ url : url, type : 'GET', contentType : 'application/json', @@ -842,8 +786,8 @@ var kimchi = { }, getStoragePoolVolume: function(poolName, volumeName, suc, err) { - var url = 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName); - kimchi.requestJSON({ + var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName); + wok.requestJSON({ url : url, type : 'GET', contentType : 'application/json', @@ -857,8 +801,8 @@ var kimchi = { addVMStorage : function(settings, suc, err) { var vm = encodeURIComponent(settings['vm']); delete settings['vm']; - kimchi.requestJSON({ - url : 'vms/' + vm + '/storages', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + vm + '/storages', type : 'POST', contentType : 'application/json', data : JSON.stringify(settings), @@ -871,8 +815,8 @@ var kimchi = { retrieveVMStorage : function(settings, suc, err) { var vm = encodeURIComponent(settings['vm']); var dev = encodeURIComponent(settings['dev']); - kimchi.requestJSON({ - url : "vms/" + vm + '/storages/' + dev, + wok.requestJSON({ + url : "plugins/kimchi/vms/" + vm + '/storages/' + dev, type : 'GET', contentType : 'application/json', dataType : 'json', @@ -884,8 +828,8 @@ var kimchi = { replaceVMStorage : function(settings, suc, err) { var vm = encodeURIComponent(settings['vm']); var dev = encodeURIComponent(settings['dev']); - kimchi.requestJSON({ - url : 'vms/' + vm + '/storages/' + dev, + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + vm + '/storages/' + dev, type : 'PUT', contentType : 'application/json', data : JSON.stringify({ @@ -900,9 +844,9 @@ var kimchi = { deleteVMStorage : function(settings, suc, err) { var vm = settings['vm']; var dev = settings['dev']; - kimchi.requestJSON({ - url : 'vms/' + encodeURIComponent(vm) + - '/storages/' + encodeURIComponent(dev), + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + + '/storages/' + encodeURIComponent(dev), type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -914,11 +858,11 @@ var kimchi = { listVMStorages : function(params, suc, err) { var vm = encodeURIComponent(params['vm']); var type = params['storageType']; - var url = 'vms/' + vm + '/storages'; + var url = 'plugins/kimchi/vms/' + vm + '/storages'; if(type) { url += '?type=' + type; } - kimchi.requestJSON({ + wok.requestJSON({ url : url, type : 'GET', contentType : 'application/json', @@ -929,8 +873,8 @@ var kimchi = { }, listSoftwareUpdates : function(suc, err) { - kimchi.requestJSON({ - url : 'host/packagesupdate', + wok.requestJSON({ + url : 'plugins/kimchi/host/packagesupdate', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -969,8 +913,8 @@ var kimchi = { } }; - kimchi.requestJSON({ - url : 'host/swupdate', + wok.requestJSON({ + url : 'plugins/kimchi/host/swupdate', type : "POST", contentType : "application/json", dataType : "json", @@ -980,8 +924,8 @@ var kimchi = { }, createRepository : function(settings, suc, err) { - kimchi.requestJSON({ - url : "host/repositories", + wok.requestJSON({ + url : "plugins/kimchi/host/repositories", type : "POST", contentType : "application/json", data : JSON.stringify(settings), @@ -993,8 +937,8 @@ var kimchi = { retrieveRepository : function(repository, suc, err) { var reposID = encodeURIComponent(repository); - kimchi.requestJSON({ - url : "host/repositories/" + reposID, + wok.requestJSON({ + url : "plugins/kimchi/host/repositories/" + reposID, type : 'GET', contentType : 'application/json', dataType : 'json', @@ -1006,7 +950,7 @@ var kimchi = { updateRepository : function(name, settings, suc, err) { var reposID = encodeURIComponent(name); $.ajax({ - url : "host/repositories/" + reposID, + url : "plugins/kimchi/host/repositories/" + reposID, type : 'PUT', contentType : 'application/json', data : JSON.stringify(settings), @@ -1019,8 +963,8 @@ var kimchi = { enableRepository : function(name, enable, suc, err) { var reposID = encodeURIComponent(name); $.ajax({ - url : "host/repositories/" + reposID + - '/' + (enable === true ? 'enable' : 'disable'), + url : "plugins/kimchi/host/repositories/" + reposID + + '/' + (enable === true ? 'enable' : 'disable'), type : 'POST', contentType : 'application/json', dataType : 'json', @@ -1031,8 +975,8 @@ var kimchi = { deleteRepository : function(repository, suc, err) { var reposID = encodeURIComponent(repository); - kimchi.requestJSON({ - url : 'host/repositories/' + reposID, + wok.requestJSON({ + url : 'plugins/kimchi/host/repositories/' + reposID, type : 'DELETE', contentType : 'application/json', dataType : 'json', @@ -1042,8 +986,8 @@ var kimchi = { }, listRepositories : function(suc, err) { - kimchi.requestJSON({ - url : 'host/repositories', + wok.requestJSON({ + url : 'plugins/kimchi/host/repositories', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -1054,77 +998,77 @@ var kimchi = { }, getHostFCDevices: function(suc, err) { - var url = 'host/devices?_cap=fc_host'; - kimchi.requestJSON({ + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getGuestInterfaces: function(name, suc, err) { - var url = 'vms/'+encodeURIComponent(name)+'/ifaces'; - kimchi.requestJSON({ + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, createGuestInterface : function(name, interface, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(name)+'/ifaces', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, deleteGuestInterface : function(vm, mac, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac), + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, updateGuestInterface : function(vm, mac, interface, suc, err) { $.ajax({ - url : 'vms/'+encodeURIComponent(vm)+'/ifaces/'+encodeURIComponent(mac), + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getUserById : function(data, suc, err) { - kimchi.requestJSON({ - url : 'users?_user_id=' + data.user_id, + wok.requestJSON({ + url : 'plugins/kimchi/users?_user_id=' + data.user_id, type : 'GET', contentType : 'application/json', dataType : 'json', @@ -1132,77 +1076,77 @@ var kimchi = { async : false, success : suc && suc(data), error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getUsers : function(suc, err) { - kimchi.requestJSON({ - url : 'users', + wok.requestJSON({ + url : 'plugins/kimchi/users', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getGroups : function(suc, err) { - kimchi.requestJSON({ - url : 'groups', + wok.requestJSON({ + url : 'plugins/kimchi/groups', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getHostPCIDevices : function(suc, err) { - kimchi.requestJSON({ - url : 'host/devices?_passthrough=true&_cap=pci', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getAvailableHostPCIDevices : function(suc, err) { - kimchi.requestJSON({ - url : 'host/devices?_passthrough=true&_cap=pci&_available_only=true', + wok.requestJSON({ + url : 'plugins/kimchi/host/devices?_passthrough=true&_cap=pci&_available_only=true', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getPCIDeviceCompanions : function(pcidev, suc, err) { - kimchi.requestJSON({ - url : 'host/devices?_passthrough_affected_by=' + pcidev, + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, @@ -1210,70 +1154,70 @@ var kimchi = { getISCSITargets : function(server, port, suc, err) { server = encodeURIComponent(server); port = port ? '&_server_port='+encodeURIComponent(port) : ''; - kimchi.requestJSON({ - url : 'storageservers/'+server+'/storagetargets?_target_type=iscsi'+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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getPeers : function(suc, err) { - kimchi.requestJSON({ - url : 'peers', + wok.requestJSON({ + url : 'plugins/kimchi/peers', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getVMPCIDevices : function(id, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(id)+'/hostdevs', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, addVMPCIDevice : function(vm, device, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+ encodeURIComponent(vm) +'/hostdevs', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, removeVMPCIDevice : function(vm, device, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+ encodeURIComponent(vm) +'/hostdevs/' + encodeURIComponent(device), + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, @@ -1282,8 +1226,8 @@ var kimchi = { * Create a new volume with capacity */ createVolumeWithCapacity: function(poolName, settings, suc, err) { - kimchi.requestJSON({ - url : 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes', + wok.requestJSON({ + url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes', type : 'POST', contentType : "application/json", data : JSON.stringify(settings), @@ -1297,9 +1241,9 @@ var kimchi = { * Upload volume content */ uploadVolumeToSP: function(poolName, volumeName, settings, suc, err) { - var url = 'storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName); + var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName); var fd = settings['formData']; - kimchi.requestJSON({ + wok.requestJSON({ url : url, type : 'PUT', data : fd, @@ -1317,8 +1261,8 @@ var kimchi = { downloadVolumeToSP: function(settings, suc, err) { var sp = encodeURIComponent(settings['sp']); delete settings['sp']; - kimchi.requestJSON({ - url : 'storagepools/' + sp + '/storagevolumes', + wok.requestJSON({ + url : 'plugins/kimchi/storagepools/' + sp + '/storagevolumes', type : 'POST', data : JSON.stringify(settings), contentType : 'application/json', @@ -1329,35 +1273,35 @@ var kimchi = { }, cloneGuest: function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+"/clone", + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + "/clone", type : 'POST', contentType : 'application/json', dataType : 'json', success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, listSnapshots : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/snapshots', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getCurrentSnapshot : function(vm, suc, err, sync) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/snapshots/current', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/current', type : 'GET', contentType : 'application/json', dataType : 'json', @@ -1365,60 +1309,60 @@ var kimchi = { resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, revertSnapshot : function(vm, snapshot, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot)+'/revert', + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, createSnapshot : function(vm, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/snapshots', + wok.requestJSON({ + url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots', type : 'POST', contentType : 'application/json', dataType : 'json', success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, deleteSnapshot : function(vm, snapshot, suc, err) { - kimchi.requestJSON({ - url : 'vms/'+encodeURIComponent(vm)+'/snapshots/'+encodeURIComponent(snapshot), + 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) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); }, getCPUInfo : function(suc, err) { - kimchi.requestJSON({ - url : 'host/cpuinfo', + wok.requestJSON({ + url : 'plugins/kimchi/host/cpuinfo', type : 'GET', contentType : 'application/json', dataType : 'json', resend : true, success : suc, error : err ? err : function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); } }); } diff --git a/ui/js/src/kimchi.guest_add_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js similarity index 86% rename from ui/js/src/kimchi.guest_add_main.js rename to plugins/kimchi/ui/js/src/kimchi.guest_add_main.js index df7697593..6be6f9a9e 100644 --- a/ui/js/src/kimchi.guest_add_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js @@ -17,7 +17,7 @@ */ kimchi.guest_add_main = function() { var showTemplates = function() { - kimchi.topic('templateCreated').unsubscribe(showTemplates); + wok.topic('templateCreated').unsubscribe(showTemplates); kimchi.listTemplates(function(result) { if (result && result.length) { $('#prompt-create-template').addClass('hidden'); @@ -25,16 +25,16 @@ kimchi.guest_add_main = function() { var html = ''; var tmpl = $('#tmpl-template').html(); $.each(result, function(index, value) { - html += kimchi.substitute(tmpl, value); + html += wok.substitute(tmpl, value); }); $('#templateTile').html(html); return; } $('#btn-create-template').on('click', function(event) { - kimchi.topic('templateCreated').subscribe(showTemplates); + wok.topic('templateCreated').subscribe(showTemplates); - kimchi.window.open('template-add.html'); + wok.window.open('plugins/kimchi/template-add.html'); event.preventDefault(); }); @@ -42,7 +42,7 @@ kimchi.guest_add_main = function() { $('#prompt-choose-template').addClass('hidden'); $('#prompt-create-template').removeClass('hidden'); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }; @@ -66,14 +66,14 @@ kimchi.guest_add_main = function() { var formData = $('#form-vm-add').serializeObject(); kimchi.createVM(formData, function() { kimchi.listVmsAuto(); - kimchi.window.close(); + 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']; - kimchi.message.error(reason); + wok.message.error(reason); }); return false; diff --git a/ui/js/src/kimchi.guest_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js similarity index 94% rename from ui/js/src/kimchi.guest_edit_main.js rename to plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js index b7ef78ec7..46de86858 100644 --- a/ui/js/src/kimchi.guest_edit_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js @@ -46,7 +46,7 @@ kimchi.guest_edit_main = function() { $.each(storages, function(index, storage) { storage['vm'] = kimchi.selectedGuest; rowHTML = $('#' + storage['type'] + '-row-tmpl').html(); - var templated = kimchi.substitute(rowHTML, storage); + var templated = wok.substitute(rowHTML, storage); container.append(templated); }); @@ -120,12 +120,12 @@ kimchi.guest_edit_main = function() { settings['content'] = i18n['KCHVMCD6009M']; var dev = $(this).data('dev'); - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.deleteVMStorage({ vm: kimchi.selectedGuest, dev: dev }, function() { - kimchi.topic('kimchi/vmCDROMDetached').publish(); + wok.topic('kimchi/vmCDROMDetached').publish(); }); }); }); @@ -140,13 +140,13 @@ kimchi.guest_edit_main = function() { }; kimchi.replaceVMStorage(settings, function(result) { - kimchi.topic('kimchi/vmCDROMReplaced').publish({ + wok.topic('kimchi/vmCDROMReplaced').publish({ result: result }); }, function(result) { var errText = result['reason'] || result['responseJSON']['reason']; - kimchi.message.error(errText); + wok.message.error(errText); }); }); @@ -183,7 +183,7 @@ kimchi.guest_edit_main = function() { if (data.id == -1) { data.id = $('#form-guest-edit-interface > .body').children().size() } - var itemNode = $.parseHTML(kimchi.substitute($('#interface-tmpl').html(),data)); + var itemNode = $.parseHTML(wok.substitute($('#interface-tmpl').html(),data)); $(".body", "#form-guest-edit-interface").append(itemNode); $("select", itemNode).append(networkOptions); if(data.network!==""){ @@ -283,7 +283,7 @@ kimchi.guest_edit_main = function() { }); }); var addItem = function(data) { - var itemNode = $.parseHTML(kimchi.substitute($('#ldap-user-tmpl').html(),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" }, @@ -367,7 +367,7 @@ kimchi.guest_edit_main = function() { var init = function(availUsers, availGroups, selUsers, selGroups){ var initNode = function(key, isUserNode){ var nodeGroups = isUserNode ? userNodes : groupNodes; - nodeGroups[key] = $.parseHTML(kimchi.substitute($('#permission-item-pam').html(), { + nodeGroups[key] = $.parseHTML(wok.substitute($('#permission-item-pam').html(), { val: key, class: isUserNode? "user-icon" : "group-icon" })); @@ -481,7 +481,7 @@ kimchi.guest_edit_main = function() { if(pciDeviceVendor!=null){ pciDeviceVendorDesc = pciDeviceVendor.description; } - var itemNode = $.parseHTML(kimchi.substitute($('#pci-tmpl').html(),{ + var itemNode = $.parseHTML(wok.substitute($('#pci-tmpl').html(),{ name: pciDeviceName, product: pciDeviceProductDesc, vendor: pciDeviceVendorDesc @@ -562,7 +562,7 @@ kimchi.guest_edit_main = function() { } }; var addItem = function(data, container) { - var itemNode = $.parseHTML(kimchi.substitute($('#snapshot-tmpl').html(),data)); + var itemNode = $.parseHTML(wok.substitute($('#snapshot-tmpl').html(),data)); $("."+container, "#form-guest-edit-snapshot").append(itemNode); $(".delete", itemNode).button({ icons: { primary: "ui-icon-trash" }, @@ -576,7 +576,7 @@ kimchi.guest_edit_main = function() { setCurrentSnapshot(); $("button", "#form-guest-edit-snapshot").button("enable"); }, function(data){ - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); $("button", "#form-guest-edit-snapshot").button("enable"); }); }); @@ -594,9 +594,9 @@ kimchi.guest_edit_main = function() { $("button", "#form-guest-edit-snapshot").button("enable"); setCurrentSnapshot(item.prop("id")); kimchi.listVmsAuto(); - kimchi.window.close(); + wok.window.close(); }, function(data){ - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); $(".icon", item).addClass("hide"); $("button", "#form-guest-edit-snapshot").button("enable"); }); @@ -615,13 +615,13 @@ kimchi.guest_edit_main = function() { listGeneratingSnapshots(); $("button", "#form-guest-edit-snapshot").button("enable"); }, function(err){ - kimchi.message.error(err.message); + wok.message.error(err.message); listGeneratingSnapshots(); $("button", "#form-guest-edit-snapshot").button("enable"); }); }; var listGeneratingSnapshots = function(){ - kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/snapshots/*'), function(tasks) { + kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/snapshots/*'), function(tasks) { $(".task", "#form-guest-edit-snapshot").empty(); for(var i=0;i .tile'); liveTile.addClass(vmObject.state); @@ -352,7 +352,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { liveTile.off("click", kimchi.openVmConsole); liveTile.on("click", kimchi.vmresume); if(vmObject.state="paused") { - liveTile.find('.overlay').attr('src',"/images/theme-default/ac24_resume.png"); + 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()}); @@ -439,7 +439,7 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) { 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"); - kimchi.confirm({ + wok.confirm({ title : i18n['KCHAPI6006M'], content : i18n['KCHVM6010M'], confirm : i18n['KCHAPI6002M'], @@ -489,10 +489,10 @@ kimchi.guestSetRequestHeader = function(xhr) { }; kimchi.guest_main = function() { - if(kimchi.tabMode['guests'] === 'admin') { + if(wok.tabMode['guests'] === 'admin') { $('.tools').attr('style','display'); $("#vm-add").on("click", function(event) { - kimchi.window.open('guest-add.html'); + wok.window.open('plugins/kimchi/guest-add.html'); }); } kimchi.guestTemplate = $('#guest-tmpl').html(); diff --git a/ui/js/src/kimchi.guest_media_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js similarity index 85% rename from ui/js/src/kimchi.guest_media_main.js rename to plugins/kimchi/ui/js/src/kimchi.guest_media_main.js index 82bceb43e..b9205277a 100644 --- a/ui/js/src/kimchi.guest_media_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js @@ -28,14 +28,14 @@ kimchi.guest_media_main = function() { $.each(storages, function(index, storage) { storage['vm'] = kimchi.selectedGuest; - var templated = kimchi.substitute(rowHTML, storage); + var templated = wok.substitute(rowHTML, storage); container.append(templated); }); var replaceCDROM = function(event) { event.preventDefault(); kimchi.selectedGuestStorage = $(this).data('dev'); - kimchi.window.open("guest-cdrom-edit.html"); + wok.window.open("plugins/kimchi/guest-cdrom-edit.html"); }; $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM); @@ -48,9 +48,9 @@ kimchi.guest_media_main = function() { var onReplaced = function(params) { refreshCDROMs(); }; - kimchi.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); + wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced); kimchi.clearGuestMedia = function() { - kimchi.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); + wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced); }; }; diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js similarity index 94% rename from ui/js/src/kimchi.guest_storage_add.main.js rename to plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js index 323695eee..ec07cf05e 100644 --- a/ui/js/src/kimchi.guest_storage_add.main.js +++ b/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js @@ -69,7 +69,7 @@ kimchi.guest_storage_add_main = function() { }); } }); - kimchi.select('guest-add-storage-pool-list', options); + wok.select('guest-add-storage-pool-list', options); } }); @@ -117,13 +117,13 @@ kimchi.guest_storage_add_main = function() { poolTextbox.change(); } var selectType = $(typeTextbox).val(); - kimchi.select('guest-storage-type-list', types); + wok.select('guest-storage-type-list', types); var validateCDROM = function(settings) { if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path'])) return true; else { - kimchi.message.error.code('KCHVMSTOR0001E'); + wok.message.error.code('KCHVMSTOR0001E'); return false; } } @@ -132,7 +132,7 @@ kimchi.guest_storage_add_main = function() { if (settings['pool'] && settings['vol']) return true; else { - kimchi.message.error.code('KCHVMSTOR0002E'); + wok.message.error.code('KCHVMSTOR0002E'); return false; } } @@ -169,14 +169,14 @@ kimchi.guest_storage_add_main = function() { $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']); kimchi.addVMStorage(settings, function(result) { - kimchi.window.close(); - kimchi.topic('kimchi/vmCDROMAttached').publish({ + wok.window.close(); + wok.topic('kimchi/vmCDROMAttached').publish({ result: result }); }, function(result) { var errText = result['reason'] || result['responseJSON']['reason']; - kimchi.message.error(errText); + wok.message.error(errText); $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c) { $(c).prop('disabled', false); diff --git a/ui/js/src/kimchi.host.js b/plugins/kimchi/ui/js/src/kimchi.host.js similarity index 91% rename from ui/js/src/kimchi.host.js rename to plugins/kimchi/ui/js/src/kimchi.host.js index c668e374f..c3765dc91 100644 --- a/ui/js/src/kimchi.host.js +++ b/plugins/kimchi/ui/js/src/kimchi.host.js @@ -78,7 +78,7 @@ kimchi.host_main = function() { 'class': 'repository-baseurl' }]; } - repositoriesGrid = new kimchi.widget.Grid({ + repositoriesGrid = new wok.widget.Grid({ container: 'repositories-grid-container', id: 'repositories-grid', title: i18n['KCHREPO6003M'], @@ -86,7 +86,8 @@ kimchi.host_main = function() { id: 'repositories-grid-add-button', label: i18n['KCHREPO6012M'], onClick: function(event) { - kimchi.window.open({url:'repository-add.html', class: repo_type}); + wok.window.open({url:'plugins/kimchi/repository-add.html', + class: repo_type}); } }, { id: 'repositories-grid-enable-button', @@ -101,7 +102,7 @@ kimchi.host_main = function() { var enable = !repository['enabled']; $(this).prop('disabled', true); kimchi.enableRepository(name, enable, function() { - kimchi.topic('kimchi/repositoryUpdated').publish(); + wok.topic('kimchi/repositoryUpdated').publish(); }); } }, { @@ -114,7 +115,8 @@ kimchi.host_main = function() { return; } kimchi.selectedRepository = repository['repo_id']; - kimchi.window.open({url:'repository-edit.html', class: repo_type}); + wok.window.open({url:'plugins/kimchi/repository-edit.html', + class: repo_type}); } }, { id: 'repositories-grid-remove-button', @@ -133,11 +135,11 @@ kimchi.host_main = function() { cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.deleteRepository( repository['repo_id'], function(result) { - kimchi.topic('kimchi/repositoryDeleted').publish(result); + wok.topic('kimchi/repositoryDeleted').publish(result); }, function(error) { } ); @@ -203,7 +205,7 @@ kimchi.host_main = function() { }; var initSoftwareUpdatesGrid = function(softwareUpdates) { - softwareUpdatesGrid = new kimchi.widget.Grid({ + softwareUpdatesGrid = new wok.widget.Grid({ container: 'software-updates-grid-container', id: softwareUpdatesGridID, title: i18n['KCHUPD6001M'], @@ -217,19 +219,19 @@ kimchi.host_main = function() { var progressArea = $('#' + progressAreaID)[0]; $('#software-updates-progress-container').removeClass('hidden'); $(progressArea).text(''); - !kimchi.isElementInViewport(progressArea) && + !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); - kimchi.topic('kimchi/softwareUpdated').publish({ + wok.topic('kimchi/softwareUpdated').publish({ result: result }); }, function(error) { var message = error && error['responseJSON'] && error['responseJSON']['reason']; - kimchi.message.error(message || i18n['KCHUPD6009M']); + wok.message.error(message || i18n['KCHUPD6009M']); $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false); }, reloadProgressArea); } @@ -287,14 +289,14 @@ kimchi.host_main = function() { var enableReportButtons = function(toEnable) { var buttonID = '#{grid}-{btn}-button'; $.each(['rename', 'remove', 'download'], function(i, n) { - $(kimchi.substitute(buttonID, { + $(wok.substitute(buttonID, { grid: reportGridID, btn: n })).prop('disabled', !toEnable); }); }; var initReportGrid = function(reports) { - reportGrid = new kimchi.widget.Grid({ + reportGrid = new wok.widget.Grid({ container: 'available-reports-grid-container', id: reportGridID, title: i18n['KCHDR6002M'], @@ -302,7 +304,7 @@ kimchi.host_main = function() { id: reportGridID + '-generate-button', label: i18n['KCHDR6006M'], onClick: function(event) { - kimchi.window.open('report-add.html'); + wok.window.open('plugins/kimchi/report-add.html'); } }, { id: reportGridID + '-rename-button', @@ -315,7 +317,7 @@ kimchi.host_main = function() { } kimchi.selectedReport = report['name']; - kimchi.window.open('report-rename.html'); + wok.window.open('plugins/kimchi/report-rename.html'); } }, { id: reportGridID + '-remove-button', @@ -334,13 +336,13 @@ kimchi.host_main = function() { cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.deleteReport({ name: report['name'] }, function(result) { listDebugReports(); }, function(error) { - kimchi.message.error(error.responseJSON.reason); + wok.message.error(error.responseJSON.reason); }); }); } @@ -389,11 +391,11 @@ kimchi.host_main = function() { var getPendingReports = function() { var reports = [] - var filter = 'status=running&target_uri=' + encodeURIComponent('^/debugreports/*') + 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(/^\/debugreports\//, '') || i18n['KCHDR6012M']; + 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) { @@ -401,7 +403,7 @@ kimchi.host_main = function() { } kimchi.trackTask(tasks[i].id, function(result) { - kimchi.topic('kimchi/debugReportAdded').publish(); + wok.topic('kimchi/debugReportAdded').publish(); }, function(result) { // Error message from Async Task status if (result['message']) { @@ -411,8 +413,8 @@ kimchi.host_main = function() { else { var errText = result['responseJSON']['reason']; } - result && kimchi.message.error(errText); - kimchi.topic('kimchi/debugReportAdded').publish(); + result && wok.message.error(errText); + wok.topic('kimchi/debugReportAdded').publish(); }, null); } }, null, true); @@ -462,7 +464,7 @@ kimchi.host_main = function() { cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.shutdown(params); $(shutdownButtonID).prop('disabled', true); $(restartButtonID).prop('disabled', true); @@ -470,7 +472,7 @@ kimchi.host_main = function() { kimchi.listVMs(function(vms) { for(var i = 0; i < vms.length; i++) { if(vms[i]['state'] === 'running') { - kimchi.message.error.code('KCHHOST6001E'); + wok.message.error.code('KCHHOST6001E'); $(shutdownButtonID).prop('disabled', false); $(restartButtonID).prop('disabled', false); return; @@ -513,18 +515,18 @@ kimchi.host_main = function() { 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']); - kimchi.topic('kimchi/repositoryAdded') + wok.topic('kimchi/repositoryAdded') .subscribe(listRepositories); - kimchi.topic('kimchi/repositoryUpdated') + wok.topic('kimchi/repositoryUpdated') .subscribe(listRepositories); - kimchi.topic('kimchi/repositoryDeleted') + wok.topic('kimchi/repositoryDeleted') .subscribe(listRepositories); } if(kimchi.capabilities['update_tool']) { $('#software-update-section').removeClass('hidden'); initSoftwareUpdatesGrid(); - kimchi.topic('kimchi/softwareUpdated') + wok.topic('kimchi/softwareUpdated') .subscribe(listSoftwareUpdates); $('#software-updates-progress-container').accordion({ collapsible: true @@ -533,9 +535,9 @@ kimchi.host_main = function() { if(kimchi.capabilities['system_report_tool']) { listDebugReports(); - kimchi.topic('kimchi/debugReportAdded') + wok.topic('kimchi/debugReportAdded') .subscribe(listDebugReports); - kimchi.topic('kimchi/debugReportRenamed') + wok.topic('kimchi/debugReportRenamed') .subscribe(listDebugReports); } }; @@ -545,10 +547,10 @@ kimchi.host_main = function() { kimchi.getHost(function(data) { var htmlTmpl = $('#host-tmpl').html(); data['logo'] = data['logo'] || ''; - data['memory'] = kimchi.formatMeasurement(data['memory'], { + data['memory'] = wok.formatMeasurement(data['memory'], { fixed: 2 }); - var templated = kimchi.substitute(htmlTmpl, data); + var templated = wok.substitute(htmlTmpl, data); $('#host-content-container').html(templated); initPage(); @@ -801,22 +803,22 @@ kimchi.host_main = function() { } var trackedCharts = { - cpu: new kimchi.widget.LineChart({ + cpu: new wok.widget.LineChart({ id: 'chart-cpu', node: 'container-chart-cpu', type: 'percent' }), - memory: new kimchi.widget.LineChart({ + memory: new wok.widget.LineChart({ id: 'chart-memory', node: 'container-chart-memory', type: 'value' }), - diskIO: new kimchi.widget.LineChart({ + diskIO: new wok.widget.LineChart({ id: 'chart-disk-io', node: 'container-chart-disk-io', type: 'value' }), - networkIO: new kimchi.widget.LineChart({ + networkIO: new wok.widget.LineChart({ id: 'chart-network-io', node: 'container-chart-network-io', type: 'value' @@ -839,18 +841,18 @@ kimchi.host_main = function() { } repositoriesGrid && repositoriesGrid.destroy(); - kimchi.topic('kimchi/repositoryAdded') + wok.topic('kimchi/repositoryAdded') .unsubscribe(listRepositories); - kimchi.topic('kimchi/repositoryUpdated') + wok.topic('kimchi/repositoryUpdated') .unsubscribe(listRepositories); - kimchi.topic('kimchi/repositoryDeleted') + wok.topic('kimchi/repositoryDeleted') .unsubscribe(listRepositories); softwareUpdatesGrid && softwareUpdatesGrid.destroy(); - kimchi.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates); + wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates); reportGrid && reportGrid.destroy(); - kimchi.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports); - kimchi.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports); + 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 new file mode 100644 index 000000000..2fdeb85fc --- /dev/null +++ b/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/ui/js/src/kimchi.network.js b/plugins/kimchi/ui/js/src/kimchi.network.js similarity index 92% rename from ui/js/src/kimchi.network.js rename to plugins/kimchi/ui/js/src/kimchi.network.js index 0421e195b..c43b59ad9 100644 --- a/ui/js/src/kimchi.network.js +++ b/plugins/kimchi/ui/js/src/kimchi.network.js @@ -19,7 +19,7 @@ kimchi.NETWORK_TYPE_BRIDGE = "bridged"; kimchi.initNetwork = function() { - if(kimchi.tabMode['network'] === 'admin') { + if(wok.tabMode['network'] === 'admin') { $('.tools').attr('style','display'); $('#network-content .header span:last-child').attr('style','display'); kimchi.initNetworkCreation(); @@ -57,7 +57,7 @@ kimchi.initNetworkListView = function() { kimchi.addNetworkItem = function(network) { var itemNode = $.parseHTML(kimchi.getNetworkItemHtml(network)); $("#networkBody").append(itemNode); - if(kimchi.tabMode["network"] === "admin") { + if(wok.tabMode["network"] === "admin") { $(".column-action").attr("style","display"); } else { $(".column-space").addClass('column-space-no-border-right'); @@ -78,7 +78,7 @@ kimchi.getNetworkItemHtml = function(network) { } var disable_in_use = network.in_use ? "ui-state-disabled" : ""; - var networkItem = kimchi.substitute($('#networkItem').html(), { + var networkItem = wok.substitute($('#networkItem').html(), { name : network.name, state : network.state, type : network.type, @@ -94,7 +94,7 @@ kimchi.getNetworkItemHtml = function(network) { }; kimchi.stopNetwork = function(network,menu) { - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("up", "nw-loading"); + $(".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"); @@ -104,23 +104,23 @@ kimchi.stopNetwork = function(network,menu) { $("[nwAct='delete']", menu).removeClass("ui-state-disabled"); $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled"); } - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("nw-loading", "down"); + $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "down"); }, function(err) { - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("nw-loading", "up"); + $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up"); if (!network.in_use) { $("[nwAct='stop']", menu).removeClass("ui-state-disabled"); } - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); } kimchi.addNetworkActions = function(network) { - $(".menu-container", "#" + kimchi.escapeStr(network.name)).menu(); + $(".menu-container", "#" + wok.escapeStr(network.name)).menu(); - $('#' + kimchi.escapeStr(network.name)).on('click', '.menu-container li', function(evt) { + $('#' + wok.escapeStr(network.name)).on('click', '.menu-container li', function(evt) { var menu = $(evt.currentTarget).parent(); if ($(evt.currentTarget).attr("nwAct") === "start") { - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("down", "nw-loading"); + $(".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); @@ -132,15 +132,15 @@ kimchi.addNetworkActions = function(network) { if (network.in_use) { $("[nwAct='stop']", menu).addClass("ui-state-disabled"); } - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("nw-loading", "up"); + $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up"); }, function(err) { - $(".network-state", $("#" + kimchi.escapeStr(network.name))).switchClass("nw-loading","down"); + $(".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"); - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); } else if ($(evt.currentTarget).attr("nwAct") === "stop") { if (network.in_use) { @@ -153,7 +153,7 @@ kimchi.addNetworkActions = function(network) { confirm : i18n['KCHAPI6002M'], cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.stopNetwork(network, menu); $('#networkGrid').grid('deleteRow', $(evt.currentTarget).parents(".row")); }, null); @@ -166,7 +166,7 @@ kimchi.addNetworkActions = function(network) { if (network.state === "up" || network.in_use) { return false; } - kimchi.confirm({ + wok.confirm({ title : i18n['KCHAPI6006M'], content : i18n['KCHNET6002M'], confirm : i18n['KCHAPI6002M'], @@ -206,7 +206,7 @@ kimchi.initNetworkCreation = function() { if ($("#enableVlan").prop("checked")) { data.vlan_id = network.vlan_id; if (!(data.vlan_id >=1 && data.vlan_id <= 4094)) { - kimchi.message.error.code('KCHNET6001E'); + wok.message.error.code('KCHNET6001E'); errorCallback(); return; } @@ -220,7 +220,7 @@ kimchi.initNetworkCreation = function() { $('#networkGrid').grid('addRow', kimchi.addNetworkItem(network)); $("#networkConfig").dialog("close"); }, function(data) { - kimchi.message.error(data.responseJSON.reason); + wok.message.error(data.responseJSON.reason); errorCallback(); }); }); @@ -375,7 +375,7 @@ kimchi.setDefaultNetworkType = function(isInterfaceAvail) { $("#networkBriDisabledLabel").show(); } else { if (kimchi.capabilities && kimchi.capabilities.nm_running) { - kimchi.message.warn(i18n['KCHNET6001W']); + wok.message.warn(i18n['KCHNET6001W']); } $("#bridgeOptions").slideDown(100); $("#networkVlanID").toggle(false); diff --git a/ui/js/src/kimchi.report_add_main.js b/plugins/kimchi/ui/js/src/kimchi.report_add_main.js similarity index 89% rename from ui/js/src/kimchi.report_add_main.js rename to plugins/kimchi/ui/js/src/kimchi.report_add_main.js index 9a7df2c36..5f098d37d 100644 --- a/ui/js/src/kimchi.report_add_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.report_add_main.js @@ -29,7 +29,7 @@ kimchi.report_add_main = function() { var reportName = nameTextbox.val(); var validator = RegExp("^[_A-Za-z0-9-]*$"); if (!validator.test(reportName)) { - kimchi.message.error.code('KCHDR6011M'); + wok.message.error.code('KCHDR6011M'); return false; } var formData = addReportForm.serializeObject(); @@ -39,13 +39,13 @@ kimchi.report_add_main = function() { return; } taskAccepted = true; - kimchi.window.close(); - kimchi.topic('kimchi/debugReportAdded').publish(); + wok.window.close(); + wok.topic('kimchi/debugReportAdded').publish(); }; kimchi.createReport(formData, function(result) { onTaskAccepted(); - kimchi.topic('kimchi/debugReportAdded').publish(); + wok.topic('kimchi/debugReportAdded').publish(); }, function(result) { // Error message from Async Task status if (result['message']) { @@ -55,7 +55,7 @@ kimchi.report_add_main = function() { else { var errText = result['responseJSON']['reason']; } - result && kimchi.message.error(errText); + result && wok.message.error(errText); taskAccepted && $('.grid-body-view table tr:first-child', diff --git a/ui/js/src/kimchi.report_rename_main.js b/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js similarity index 89% rename from ui/js/src/kimchi.report_rename_main.js rename to plugins/kimchi/ui/js/src/kimchi.report_rename_main.js index 6ee56d9c2..1bdb8d9f5 100644 --- a/ui/js/src/kimchi.report_rename_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js @@ -28,13 +28,13 @@ kimchi.report_rename_main = function() { // if the user hasn't changed the report's name, // nothing should be done. if (reportName == kimchi.selectedReport) { - kimchi.message.error.code('KCHDR6013M'); + wok.message.error.code('KCHDR6013M'); return false; } var validator = RegExp("^[A-Za-z0-9-]*$"); if (!validator.test(reportName)) { - kimchi.message.error.code('KCHDR6011M'); + wok.message.error.code('KCHDR6011M'); return false; } var formData = renameReportForm.serializeObject(); @@ -43,15 +43,15 @@ kimchi.report_rename_main = function() { kimchi.renameReport(kimchi.selectedReport, formData, function(result) { submitButton.prop('disabled', false); nameTextbox.prop('disabled', false); - kimchi.window.close(); - kimchi.topic('kimchi/debugReportRenamed').publish({ + wok.window.close(); + wok.topic('kimchi/debugReportRenamed').publish({ result: result }); }, function(result) { var errText = result && result['responseJSON'] && result['responseJSON']['reason']; - kimchi.message.error(errText); + wok.message.error(errText); submitButton.prop('disabled', false); nameTextbox.prop('disabled', false).focus(); }); diff --git a/ui/js/src/kimchi.repository_add_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js similarity index 95% rename from ui/js/src/kimchi.repository_add_main.js rename to plugins/kimchi/ui/js/src/kimchi.repository_add_main.js index 2a277fd71..656306b23 100644 --- a/ui/js/src/kimchi.repository_add_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js @@ -81,13 +81,13 @@ kimchi.repository_add_main = function() { } kimchi.createRepository(formData, function() { - kimchi.topic('kimchi/repositoryAdded').publish(); - kimchi.window.close(); + wok.topic('kimchi/repositoryAdded').publish(); + wok.window.close(); }, function(jqXHR, textStatus, errorThrown) { var reason = jqXHR && jqXHR['responseJSON'] && jqXHR['responseJSON']['reason']; - kimchi.message.error(reason); + wok.message.error(reason); }); return false; }; diff --git a/ui/js/src/kimchi.repository_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js similarity index 94% rename from ui/js/src/kimchi.repository_edit_main.js rename to plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js index a9a0ca69b..5bfc51e8c 100644 --- a/ui/js/src/kimchi.repository_edit_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js @@ -57,13 +57,13 @@ kimchi.repository_edit_main = function() { } kimchi.updateRepository(kimchi.selectedRepository, formData, function() { - kimchi.topic('kimchi/repositoryUpdated').publish(); - kimchi.window.close(); + wok.topic('kimchi/repositoryUpdated').publish(); + wok.window.close(); }, function(jqXHR, textStatus, errorThrown) { var reason = jqXHR && jqXHR['responseJSON'] && jqXHR['responseJSON']['reason']; - kimchi.message.error(reason); + wok.message.error(reason); }); return false; diff --git a/ui/js/src/kimchi.storage_main.js b/plugins/kimchi/ui/js/src/kimchi.storage_main.js similarity index 86% rename from ui/js/src/kimchi.storage_main.js rename to plugins/kimchi/ui/js/src/kimchi.storage_main.js index 6125da9cc..40a43f623 100644 --- a/ui/js/src/kimchi.storage_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.storage_main.js @@ -22,17 +22,17 @@ kimchi.doListStoragePools = function() { var listHtml = ''; $.each(result, function(index, value) { value.usage = Math.round(value.allocated / value.capacity * 100) || 0; - value.capacity = kimchi.changetoProperUnit(value.capacity,1); - value.allocated = kimchi.changetoProperUnit(value.allocated,1); + 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 += kimchi.substitute(storageHtml, value); + listHtml += wok.substitute(storageHtml, value); } }); if($('#storageGrid').hasClass('grid')) $('#storageGrid').grid('destroy'); $('#storagepoolsList').html(listHtml); - if(kimchi.tabMode['storage'] === 'admin') { + if(wok.tabMode['storage'] === 'admin') { $('.storage-button').attr('style','display'); } else { $('.storage-allocate').addClass('storage-allocate-padding-user'); @@ -46,7 +46,7 @@ kimchi.doListStoragePools = function() { $('#storagepoolsList').html(''); } }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); } @@ -97,7 +97,7 @@ kimchi.storageBindClick = function() { } }); - if(kimchi.tabMode['storage'] === 'admin') { + if(wok.tabMode['storage'] === 'admin') { $('.pool-delete').on('click', function(event) { var $pool = $(this); var settings = { @@ -106,12 +106,12 @@ kimchi.storageBindClick = function() { confirm : i18n['KCHAPI6002M'], cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { var poolName = $pool.data('name'); kimchi.deleteStoragePool(poolName, function() { kimchi.doListStoragePools(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }); }); @@ -121,7 +121,7 @@ kimchi.storageBindClick = function() { kimchi.changePoolState(poolName, 'activate', function() { kimchi.doListStoragePools(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }); @@ -134,11 +134,11 @@ kimchi.storageBindClick = function() { cancel : i18n['KCHAPI6003M'] }; if (!$(this).data('persistent')) { - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { kimchi.changePoolState(poolName, 'deactivate', function() { kimchi.doListStoragePools(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }, function() { return false; @@ -148,7 +148,7 @@ kimchi.storageBindClick = function() { kimchi.changePoolState(poolName, 'deactivate', function() { kimchi.doListStoragePools(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); } }); @@ -156,7 +156,7 @@ kimchi.storageBindClick = function() { $('.pool-add-volume').on('click', function(event) { var poolName = $(this).data('name'); kimchi.selectedSP = poolName; - kimchi.window.open('storagepool-add-volume.html'); + wok.window.open('plugins/kimchi/storagepool-add-volume.html'); }); $('.storage-action').on('click', function() { @@ -201,9 +201,9 @@ kimchi._generateVolumeHTML = function(volume) { return ''; } var volumeHtml = $('#volumeTmpl').html(); - volume.capacity = kimchi.changetoProperUnit(volume.capacity,1); - volume.allocation = kimchi.changetoProperUnit(volume.allocation,1); - return kimchi.substitute(volumeHtml, volume); + volume.capacity = wok.changetoProperUnit(volume.capacity,1); + volume.allocation = wok.changetoProperUnit(volume.allocation,1); + return wok.substitute(volumeHtml, volume); }; kimchi.doListVolumes = function(poolObj) { @@ -211,7 +211,7 @@ kimchi.doListVolumes = function(poolObj) { var getOngoingVolumes = function() { var result = {} - var filter = 'status=running&target_uri=' + encodeURIComponent('^/storagepools/' + poolName + '/*') + 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(); @@ -222,11 +222,11 @@ kimchi.doListVolumes = function(poolObj) { } kimchi.trackTask(tasks[i].id, function(result) { - kimchi.topic('kimchi/volumeTransferFinished').publish(result); + wok.topic('kimchi/volumeTransferFinished').publish(result); }, function(result) { - kimchi.topic('kimchi/volumeTransferError').publish(result); + wok.topic('kimchi/volumeTransferError').publish(result); }, function(result) { - kimchi.topic('kimchi/volumeTransferProgress').publish(result); + wok.topic('kimchi/volumeTransferProgress').publish(result); }); } }, null, true); @@ -274,14 +274,14 @@ kimchi.doListVolumes = function(poolObj) { } $.each(ongoingVolumesMap, function(volumeName, task) { - kimchi.topic('kimchi/volumeTransferProgress').publish(task); + wok.topic('kimchi/volumeTransferProgress').publish(task); }); poolObj.removeClass('in'); kimchi.changeArrow(handleArrow); slide.slideDown('slow'); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); } @@ -300,7 +300,7 @@ kimchi.initLogicalPoolExtend = function() { if (data.length > 0) { for(var i=0;iinput').prop('checked', false); kimchi.doListTemplates(); - kimchi.topic('templateCreated').publish(data); + wok.topic('templateCreated').publish(data); if (successNum === length) { - kimchi.window.close(); + wok.window.close(); } }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }; if (formData.iso instanceof Array) { diff --git a/ui/js/src/kimchi.template_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js similarity index 96% rename from ui/js/src/kimchi.template_edit_main.js rename to plugins/kimchi/ui/js/src/kimchi.template_edit_main.js index 5b2fa75ee..b4e9c6963 100644 --- a/ui/js/src/kimchi.template_edit_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js @@ -47,7 +47,7 @@ kimchi.template_edit_main = function() { var vncOpt = [{label: 'VNC', value: 'vnc'}]; $('#template-edit-graphics').append(''); $('#template-edit-graphics').append(''); - kimchi.select('template-edit-graphics-list', vncOpt); + wok.select('template-edit-graphics-list', vncOpt); var enableSpice = function() { if (kimchi.capabilities == undefined) { setTimeout(enableSpice, 2000); @@ -55,7 +55,7 @@ kimchi.template_edit_main = function() { } if (kimchi.capabilities.qemu_spice == true) { spiceOpt = [{label: 'Spice', value: 'spice'}] - kimchi.select('template-edit-graphics-list', spiceOpt); + wok.select('template-edit-graphics-list', spiceOpt); } }; var isImageBasedTemplate = function() { @@ -69,7 +69,7 @@ kimchi.template_edit_main = function() { var scsipools = {}; var addStorageItem = function(storageData) { var thisName = storageData.storageName; - var nodeStorage = $.parseHTML(kimchi.substitute($('#template-storage-pool-tmpl').html(), storageData)); + var nodeStorage = $.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(), storageData)); $('.template-tab-body', '#form-template-storage').append(nodeStorage); var storageOptions = ''; var scsiOptions = ''; @@ -202,7 +202,7 @@ kimchi.template_edit_main = function() { var networkItemNum = 0; var addInterfaceItem = function(networkData) { var networkName = networkData.networkV; - var nodeInterface = $.parseHTML(kimchi.substitute($('#template-interface-tmpl').html(), networkData)); + 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'}, @@ -300,7 +300,7 @@ kimchi.template_edit_main = function() { if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() == 'scsi') { tempNameTail = tempName[tempName.length-1]; } - tempName = '/storagepools/' + tempNameHead; + tempName = '/plugins/kimchi/storagepools/' + tempNameHead; data['storagepool'] = tempName; $.each(editableFields, function(i, field) { /* Support only 1 disk at this moment */ @@ -352,9 +352,9 @@ kimchi.template_edit_main = function() { kimchi.updateTemplate($('#template-name').val(), data, function() { kimchi.doListTemplates(); - kimchi.window.close(); + wok.window.close(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }); }; diff --git a/ui/js/src/kimchi.template_main.js b/plugins/kimchi/ui/js/src/kimchi.template_main.js similarity index 83% rename from ui/js/src/kimchi.template_main.js rename to plugins/kimchi/ui/js/src/kimchi.template_main.js index 775cb0bf6..b09fe12da 100644 --- a/ui/js/src/kimchi.template_main.js +++ b/plugins/kimchi/ui/js/src/kimchi.template_main.js @@ -34,11 +34,11 @@ kimchi.doListTemplates = function() { } } if(isLocal){ - value.location = "images/theme-default/icon-local.png"; + value.location = "plugins/kimchi/images/theme-default/icon-local.png"; }else{ - value.location = "images/theme-default/icon-remote.png"; + value.location = "plugins/kimchi/images/theme-default/icon-remote.png"; } - listHtml += kimchi.substitute(templateHtml, value); + listHtml += wok.substitute(templateHtml, value); }); $('#templateList').html(listHtml); kimchi.templateBindClick(); @@ -48,7 +48,7 @@ kimchi.doListTemplates = function() { } $('html').removeClass('processing'); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); $('html').removeClass('processing'); }); }; @@ -57,7 +57,7 @@ kimchi.templateBindClick = function() { $('.template-edit').on('click', function(event) { var templateName = $(this).data('template'); kimchi.selectedTemplate = templateName; - kimchi.window.open("template-edit.html"); + wok.window.open("plugins/kimchi/template-edit.html"); }); $('.template-clone').on('click', function(event) { kimchi.selectedTemplate = $(this).data('template'); @@ -65,7 +65,7 @@ kimchi.templateBindClick = function() { kimchi.cloneTemplate(kimchi.selectedTemplate, function() { kimchi.doListTemplates(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); kimchi.doListTemplates(); }); }); @@ -77,12 +77,12 @@ kimchi.templateBindClick = function() { confirm : i18n['KCHAPI6002M'], cancel : i18n['KCHAPI6003M'] }; - kimchi.confirm(settings, function() { + wok.confirm(settings, function() { var templateName = $template.data('template'); kimchi.deleteTemplate(templateName, function() { kimchi.doListTemplates(); }, function(err) { - kimchi.message.error(err.responseJSON.reason); + wok.message.error(err.responseJSON.reason); }); }, function() { }); @@ -93,11 +93,11 @@ kimchi.hideTitle = function() { }; kimchi.template_main = function() { - if(kimchi.tabMode['templates'] === 'admin') { + if(wok.tabMode['templates'] === 'admin') { $('.tools').attr('style','display'); $("#template-add").on("click", function(event) { - kimchi.window.open({ - url: 'template-add.html', + wok.window.open({ + url: 'plugins/kimchi/template-add.html', close: function() { if (kimchi.deepScanHandler) { kimchi.deepScanHandler.stop = true; diff --git a/plugins/kimchi/ui/pages/Makefile.am b/plugins/kimchi/ui/pages/Makefile.am new file mode 100644 index 000000000..56288e32d --- /dev/null +++ b/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/ui/pages/guest-add.html.tmpl b/plugins/kimchi/ui/pages/guest-add.html.tmpl similarity index 98% rename from ui/pages/guest-add.html.tmpl rename to plugins/kimchi/ui/pages/guest-add.html.tmpl index f479d3d12..3770d967d 100644 --- a/ui/pages/guest-add.html.tmpl +++ b/plugins/kimchi/ui/pages/guest-add.html.tmpl @@ -17,7 +17,7 @@ *# #unicode UTF-8 #import gettext -#from kimchi.cachebust import href +#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 @@ -61,7 +61,7 @@ + +
+ + diff --git a/ui/pages/help/Makefile.am b/plugins/kimchi/ui/pages/help/Makefile.am similarity index 85% rename from ui/pages/help/Makefile.am rename to plugins/kimchi/ui/pages/help/Makefile.am index 5c0431926..a4ee36117 100644 --- a/ui/pages/help/Makefile.am +++ b/plugins/kimchi/ui/pages/help/Makefile.am @@ -20,14 +20,13 @@ 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 = gen-index.py\ - $(DITA_XSL_FILE) -helpdir = $(datadir)/kimchi/ui/pages/help +EXTRA_DIST = $(DITA_XSL_FILE) + +helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help dist_help_DATA = kimchi.css all: $(HTML_FILES) $(wildcard */*.dita) - @$(foreach dir, $(dir $(wildcard */)), $(shell pwd)/gen-index.py $(wildcard $(dir)*.dita) > $(dir)/index.html;) %.html: %.dita $(DITA_XSL_FILE) xsltproc -o $@ $(DITA_XSL_FILE) $< diff --git a/ui/pages/help/de_DE/Makefile.am b/plugins/kimchi/ui/pages/help/de_DE/Makefile.am similarity index 92% rename from ui/pages/help/de_DE/Makefile.am rename to plugins/kimchi/ui/pages/help/de_DE/Makefile.am index ab1c76996..3d99aaeae 100644 --- a/ui/pages/help/de_DE/Makefile.am +++ b/plugins/kimchi/ui/pages/help/de_DE/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/de_DE +de_DE_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/de_DE dist_de_DE_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/de_DE/guests.dita b/plugins/kimchi/ui/pages/help/de_DE/guests.dita similarity index 100% rename from ui/pages/help/de_DE/guests.dita rename to plugins/kimchi/ui/pages/help/de_DE/guests.dita diff --git a/ui/pages/help/de_DE/host.dita b/plugins/kimchi/ui/pages/help/de_DE/host.dita similarity index 100% rename from ui/pages/help/de_DE/host.dita rename to plugins/kimchi/ui/pages/help/de_DE/host.dita diff --git a/ui/pages/help/de_DE/network.dita b/plugins/kimchi/ui/pages/help/de_DE/network.dita similarity index 100% rename from ui/pages/help/de_DE/network.dita rename to plugins/kimchi/ui/pages/help/de_DE/network.dita diff --git a/ui/pages/help/de_DE/storage.dita b/plugins/kimchi/ui/pages/help/de_DE/storage.dita similarity index 100% rename from ui/pages/help/de_DE/storage.dita rename to plugins/kimchi/ui/pages/help/de_DE/storage.dita diff --git a/ui/pages/help/de_DE/templates.dita b/plugins/kimchi/ui/pages/help/de_DE/templates.dita similarity index 100% rename from ui/pages/help/de_DE/templates.dita rename to plugins/kimchi/ui/pages/help/de_DE/templates.dita diff --git a/ui/pages/help/dita-help.xsl b/plugins/kimchi/ui/pages/help/dita-help.xsl similarity index 92% rename from ui/pages/help/dita-help.xsl rename to plugins/kimchi/ui/pages/help/dita-help.xsl index 8583a4ef8..45f0a3bf1 100644 --- a/ui/pages/help/dita-help.xsl +++ b/plugins/kimchi/ui/pages/help/dita-help.xsl @@ -9,7 +9,7 @@ <xsl:value-of select="/cshelp/title" /> - + diff --git a/ui/pages/help/en_US/Makefile.am b/plugins/kimchi/ui/pages/help/en_US/Makefile.am similarity index 92% rename from ui/pages/help/en_US/Makefile.am rename to plugins/kimchi/ui/pages/help/en_US/Makefile.am index d5ab24f5e..d37f03a87 100644 --- a/ui/pages/help/en_US/Makefile.am +++ b/plugins/kimchi/ui/pages/help/en_US/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/en_US +en_US_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/en_US dist_en_US_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/en_US/guests.dita b/plugins/kimchi/ui/pages/help/en_US/guests.dita similarity index 100% rename from ui/pages/help/en_US/guests.dita rename to plugins/kimchi/ui/pages/help/en_US/guests.dita diff --git a/ui/pages/help/en_US/host.dita b/plugins/kimchi/ui/pages/help/en_US/host.dita similarity index 100% rename from ui/pages/help/en_US/host.dita rename to plugins/kimchi/ui/pages/help/en_US/host.dita diff --git a/ui/pages/help/en_US/network.dita b/plugins/kimchi/ui/pages/help/en_US/network.dita similarity index 100% rename from ui/pages/help/en_US/network.dita rename to plugins/kimchi/ui/pages/help/en_US/network.dita diff --git a/ui/pages/help/en_US/storage.dita b/plugins/kimchi/ui/pages/help/en_US/storage.dita similarity index 100% rename from ui/pages/help/en_US/storage.dita rename to plugins/kimchi/ui/pages/help/en_US/storage.dita diff --git a/ui/pages/help/en_US/templates.dita b/plugins/kimchi/ui/pages/help/en_US/templates.dita similarity index 100% rename from ui/pages/help/en_US/templates.dita rename to plugins/kimchi/ui/pages/help/en_US/templates.dita diff --git a/ui/pages/help/es_ES/Makefile.am b/plugins/kimchi/ui/pages/help/es_ES/Makefile.am similarity index 92% rename from ui/pages/help/es_ES/Makefile.am rename to plugins/kimchi/ui/pages/help/es_ES/Makefile.am index a3317a6c1..29c596fbe 100644 --- a/ui/pages/help/es_ES/Makefile.am +++ b/plugins/kimchi/ui/pages/help/es_ES/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/es_ES +es_ES_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/es_ES dist_es_ES_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/es_ES/guests.dita b/plugins/kimchi/ui/pages/help/es_ES/guests.dita similarity index 100% rename from ui/pages/help/es_ES/guests.dita rename to plugins/kimchi/ui/pages/help/es_ES/guests.dita diff --git a/ui/pages/help/es_ES/host.dita b/plugins/kimchi/ui/pages/help/es_ES/host.dita similarity index 100% rename from ui/pages/help/es_ES/host.dita rename to plugins/kimchi/ui/pages/help/es_ES/host.dita diff --git a/ui/pages/help/es_ES/network.dita b/plugins/kimchi/ui/pages/help/es_ES/network.dita similarity index 100% rename from ui/pages/help/es_ES/network.dita rename to plugins/kimchi/ui/pages/help/es_ES/network.dita diff --git a/ui/pages/help/es_ES/storage.dita b/plugins/kimchi/ui/pages/help/es_ES/storage.dita similarity index 100% rename from ui/pages/help/es_ES/storage.dita rename to plugins/kimchi/ui/pages/help/es_ES/storage.dita diff --git a/ui/pages/help/es_ES/templates.dita b/plugins/kimchi/ui/pages/help/es_ES/templates.dita similarity index 100% rename from ui/pages/help/es_ES/templates.dita rename to plugins/kimchi/ui/pages/help/es_ES/templates.dita diff --git a/ui/pages/help/fr_FR/Makefile.am b/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am similarity index 92% rename from ui/pages/help/fr_FR/Makefile.am rename to plugins/kimchi/ui/pages/help/fr_FR/Makefile.am index a5eba5ae9..11ce39415 100644 --- a/ui/pages/help/fr_FR/Makefile.am +++ b/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/fr_FR +fr_FR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/fr_FR dist_fr_FR_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/fr_FR/guests.dita b/plugins/kimchi/ui/pages/help/fr_FR/guests.dita similarity index 100% rename from ui/pages/help/fr_FR/guests.dita rename to plugins/kimchi/ui/pages/help/fr_FR/guests.dita diff --git a/ui/pages/help/fr_FR/host.dita b/plugins/kimchi/ui/pages/help/fr_FR/host.dita similarity index 100% rename from ui/pages/help/fr_FR/host.dita rename to plugins/kimchi/ui/pages/help/fr_FR/host.dita diff --git a/ui/pages/help/fr_FR/network.dita b/plugins/kimchi/ui/pages/help/fr_FR/network.dita similarity index 100% rename from ui/pages/help/fr_FR/network.dita rename to plugins/kimchi/ui/pages/help/fr_FR/network.dita diff --git a/ui/pages/help/fr_FR/storage.dita b/plugins/kimchi/ui/pages/help/fr_FR/storage.dita similarity index 100% rename from ui/pages/help/fr_FR/storage.dita rename to plugins/kimchi/ui/pages/help/fr_FR/storage.dita diff --git a/ui/pages/help/fr_FR/templates.dita b/plugins/kimchi/ui/pages/help/fr_FR/templates.dita similarity index 100% rename from ui/pages/help/fr_FR/templates.dita rename to plugins/kimchi/ui/pages/help/fr_FR/templates.dita diff --git a/ui/pages/help/it_IT/Makefile.am b/plugins/kimchi/ui/pages/help/it_IT/Makefile.am similarity index 92% rename from ui/pages/help/it_IT/Makefile.am rename to plugins/kimchi/ui/pages/help/it_IT/Makefile.am index c828f2613..62e2f291f 100644 --- a/ui/pages/help/it_IT/Makefile.am +++ b/plugins/kimchi/ui/pages/help/it_IT/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/it_IT +it_IT_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/it_IT dist_it_IT_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/it_IT/guests.dita b/plugins/kimchi/ui/pages/help/it_IT/guests.dita similarity index 100% rename from ui/pages/help/it_IT/guests.dita rename to plugins/kimchi/ui/pages/help/it_IT/guests.dita diff --git a/ui/pages/help/it_IT/host.dita b/plugins/kimchi/ui/pages/help/it_IT/host.dita similarity index 100% rename from ui/pages/help/it_IT/host.dita rename to plugins/kimchi/ui/pages/help/it_IT/host.dita diff --git a/ui/pages/help/it_IT/network.dita b/plugins/kimchi/ui/pages/help/it_IT/network.dita similarity index 100% rename from ui/pages/help/it_IT/network.dita rename to plugins/kimchi/ui/pages/help/it_IT/network.dita diff --git a/ui/pages/help/it_IT/storage.dita b/plugins/kimchi/ui/pages/help/it_IT/storage.dita similarity index 100% rename from ui/pages/help/it_IT/storage.dita rename to plugins/kimchi/ui/pages/help/it_IT/storage.dita diff --git a/ui/pages/help/it_IT/templates.dita b/plugins/kimchi/ui/pages/help/it_IT/templates.dita similarity index 100% rename from ui/pages/help/it_IT/templates.dita rename to plugins/kimchi/ui/pages/help/it_IT/templates.dita diff --git a/ui/pages/help/ja_JP/Makefile.am b/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am similarity index 92% rename from ui/pages/help/ja_JP/Makefile.am rename to plugins/kimchi/ui/pages/help/ja_JP/Makefile.am index a7d646408..f9c2f3338 100644 --- a/ui/pages/help/ja_JP/Makefile.am +++ b/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/ja_JP +ja_JP_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ja_JP dist_ja_JP_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/ja_JP/guests.dita b/plugins/kimchi/ui/pages/help/ja_JP/guests.dita similarity index 100% rename from ui/pages/help/ja_JP/guests.dita rename to plugins/kimchi/ui/pages/help/ja_JP/guests.dita diff --git a/ui/pages/help/ja_JP/host.dita b/plugins/kimchi/ui/pages/help/ja_JP/host.dita similarity index 100% rename from ui/pages/help/ja_JP/host.dita rename to plugins/kimchi/ui/pages/help/ja_JP/host.dita diff --git a/ui/pages/help/ja_JP/network.dita b/plugins/kimchi/ui/pages/help/ja_JP/network.dita similarity index 100% rename from ui/pages/help/ja_JP/network.dita rename to plugins/kimchi/ui/pages/help/ja_JP/network.dita diff --git a/ui/pages/help/ja_JP/storage.dita b/plugins/kimchi/ui/pages/help/ja_JP/storage.dita similarity index 100% rename from ui/pages/help/ja_JP/storage.dita rename to plugins/kimchi/ui/pages/help/ja_JP/storage.dita diff --git a/ui/pages/help/ja_JP/templates.dita b/plugins/kimchi/ui/pages/help/ja_JP/templates.dita similarity index 100% rename from ui/pages/help/ja_JP/templates.dita rename to plugins/kimchi/ui/pages/help/ja_JP/templates.dita diff --git a/ui/pages/help/kimchi.css b/plugins/kimchi/ui/pages/help/kimchi.css similarity index 100% rename from ui/pages/help/kimchi.css rename to plugins/kimchi/ui/pages/help/kimchi.css diff --git a/ui/pages/help/ko_KR/Makefile.am b/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am similarity index 92% rename from ui/pages/help/ko_KR/Makefile.am rename to plugins/kimchi/ui/pages/help/ko_KR/Makefile.am index 3242ad73b..e441955d7 100644 --- a/ui/pages/help/ko_KR/Makefile.am +++ b/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/ko_KR +ko_KR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ko_KR dist_ko_KR_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/ko_KR/guests.dita b/plugins/kimchi/ui/pages/help/ko_KR/guests.dita similarity index 100% rename from ui/pages/help/ko_KR/guests.dita rename to plugins/kimchi/ui/pages/help/ko_KR/guests.dita diff --git a/ui/pages/help/ko_KR/host.dita b/plugins/kimchi/ui/pages/help/ko_KR/host.dita similarity index 100% rename from ui/pages/help/ko_KR/host.dita rename to plugins/kimchi/ui/pages/help/ko_KR/host.dita diff --git a/ui/pages/help/ko_KR/network.dita b/plugins/kimchi/ui/pages/help/ko_KR/network.dita similarity index 100% rename from ui/pages/help/ko_KR/network.dita rename to plugins/kimchi/ui/pages/help/ko_KR/network.dita diff --git a/ui/pages/help/ko_KR/storage.dita b/plugins/kimchi/ui/pages/help/ko_KR/storage.dita similarity index 100% rename from ui/pages/help/ko_KR/storage.dita rename to plugins/kimchi/ui/pages/help/ko_KR/storage.dita diff --git a/ui/pages/help/ko_KR/templates.dita b/plugins/kimchi/ui/pages/help/ko_KR/templates.dita similarity index 100% rename from ui/pages/help/ko_KR/templates.dita rename to plugins/kimchi/ui/pages/help/ko_KR/templates.dita diff --git a/ui/pages/help/pt_BR/Makefile.am b/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am similarity index 92% rename from ui/pages/help/pt_BR/Makefile.am rename to plugins/kimchi/ui/pages/help/pt_BR/Makefile.am index 0f1df92c6..7fc2cb061 100644 --- a/ui/pages/help/pt_BR/Makefile.am +++ b/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/pt_BR +pt_BR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/pt_BR dist_pt_BR_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/pt_BR/guests.dita b/plugins/kimchi/ui/pages/help/pt_BR/guests.dita similarity index 100% rename from ui/pages/help/pt_BR/guests.dita rename to plugins/kimchi/ui/pages/help/pt_BR/guests.dita diff --git a/ui/pages/help/pt_BR/host.dita b/plugins/kimchi/ui/pages/help/pt_BR/host.dita similarity index 100% rename from ui/pages/help/pt_BR/host.dita rename to plugins/kimchi/ui/pages/help/pt_BR/host.dita diff --git a/ui/pages/help/pt_BR/network.dita b/plugins/kimchi/ui/pages/help/pt_BR/network.dita similarity index 100% rename from ui/pages/help/pt_BR/network.dita rename to plugins/kimchi/ui/pages/help/pt_BR/network.dita diff --git a/ui/pages/help/pt_BR/storage.dita b/plugins/kimchi/ui/pages/help/pt_BR/storage.dita similarity index 100% rename from ui/pages/help/pt_BR/storage.dita rename to plugins/kimchi/ui/pages/help/pt_BR/storage.dita diff --git a/ui/pages/help/pt_BR/templates.dita b/plugins/kimchi/ui/pages/help/pt_BR/templates.dita similarity index 100% rename from ui/pages/help/pt_BR/templates.dita rename to plugins/kimchi/ui/pages/help/pt_BR/templates.dita diff --git a/ui/pages/help/ru_RU/Makefile.am b/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am similarity index 92% rename from ui/pages/help/ru_RU/Makefile.am rename to plugins/kimchi/ui/pages/help/ru_RU/Makefile.am index b128c6d32..85ca27aa1 100644 --- a/ui/pages/help/ru_RU/Makefile.am +++ b/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/ru_RU +ru_RU_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ru_RU dist_ru_RU_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/ru_RU/guests.dita b/plugins/kimchi/ui/pages/help/ru_RU/guests.dita similarity index 100% rename from ui/pages/help/ru_RU/guests.dita rename to plugins/kimchi/ui/pages/help/ru_RU/guests.dita diff --git a/ui/pages/help/ru_RU/host.dita b/plugins/kimchi/ui/pages/help/ru_RU/host.dita similarity index 100% rename from ui/pages/help/ru_RU/host.dita rename to plugins/kimchi/ui/pages/help/ru_RU/host.dita diff --git a/ui/pages/help/ru_RU/network.dita b/plugins/kimchi/ui/pages/help/ru_RU/network.dita similarity index 100% rename from ui/pages/help/ru_RU/network.dita rename to plugins/kimchi/ui/pages/help/ru_RU/network.dita diff --git a/ui/pages/help/ru_RU/storage.dita b/plugins/kimchi/ui/pages/help/ru_RU/storage.dita similarity index 100% rename from ui/pages/help/ru_RU/storage.dita rename to plugins/kimchi/ui/pages/help/ru_RU/storage.dita diff --git a/ui/pages/help/ru_RU/templates.dita b/plugins/kimchi/ui/pages/help/ru_RU/templates.dita similarity index 100% rename from ui/pages/help/ru_RU/templates.dita rename to plugins/kimchi/ui/pages/help/ru_RU/templates.dita diff --git a/ui/pages/help/zh_CN/Makefile.am b/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am similarity index 92% rename from ui/pages/help/zh_CN/Makefile.am rename to plugins/kimchi/ui/pages/help/zh_CN/Makefile.am index 8b812ff26..e78504889 100644 --- a/ui/pages/help/zh_CN/Makefile.am +++ b/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/zh_CN +zh_CN_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_CN dist_zh_CN_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/zh_CN/guests.dita b/plugins/kimchi/ui/pages/help/zh_CN/guests.dita similarity index 100% rename from ui/pages/help/zh_CN/guests.dita rename to plugins/kimchi/ui/pages/help/zh_CN/guests.dita diff --git a/ui/pages/help/zh_CN/host.dita b/plugins/kimchi/ui/pages/help/zh_CN/host.dita similarity index 100% rename from ui/pages/help/zh_CN/host.dita rename to plugins/kimchi/ui/pages/help/zh_CN/host.dita diff --git a/ui/pages/help/zh_CN/network.dita b/plugins/kimchi/ui/pages/help/zh_CN/network.dita similarity index 100% rename from ui/pages/help/zh_CN/network.dita rename to plugins/kimchi/ui/pages/help/zh_CN/network.dita diff --git a/ui/pages/help/zh_CN/storage.dita b/plugins/kimchi/ui/pages/help/zh_CN/storage.dita similarity index 100% rename from ui/pages/help/zh_CN/storage.dita rename to plugins/kimchi/ui/pages/help/zh_CN/storage.dita diff --git a/ui/pages/help/zh_CN/templates.dita b/plugins/kimchi/ui/pages/help/zh_CN/templates.dita similarity index 100% rename from ui/pages/help/zh_CN/templates.dita rename to plugins/kimchi/ui/pages/help/zh_CN/templates.dita diff --git a/ui/pages/help/zh_TW/Makefile.am b/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am similarity index 92% rename from ui/pages/help/zh_TW/Makefile.am rename to plugins/kimchi/ui/pages/help/zh_TW/Makefile.am index 911d73778..9c8ac2630 100644 --- a/ui/pages/help/zh_TW/Makefile.am +++ b/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am @@ -14,7 +14,7 @@ # 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)/kimchi/ui/pages/help/zh_TW +zh_TW_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_TW dist_zh_TW_help_DATA = $(wildcard *.html) $(NULL) diff --git a/ui/pages/help/zh_TW/guests.dita b/plugins/kimchi/ui/pages/help/zh_TW/guests.dita similarity index 100% rename from ui/pages/help/zh_TW/guests.dita rename to plugins/kimchi/ui/pages/help/zh_TW/guests.dita diff --git a/ui/pages/help/zh_TW/host.dita b/plugins/kimchi/ui/pages/help/zh_TW/host.dita similarity index 100% rename from ui/pages/help/zh_TW/host.dita rename to plugins/kimchi/ui/pages/help/zh_TW/host.dita diff --git a/ui/pages/help/zh_TW/network.dita b/plugins/kimchi/ui/pages/help/zh_TW/network.dita similarity index 100% rename from ui/pages/help/zh_TW/network.dita rename to plugins/kimchi/ui/pages/help/zh_TW/network.dita diff --git a/ui/pages/help/zh_TW/storage.dita b/plugins/kimchi/ui/pages/help/zh_TW/storage.dita similarity index 100% rename from ui/pages/help/zh_TW/storage.dita rename to plugins/kimchi/ui/pages/help/zh_TW/storage.dita diff --git a/ui/pages/help/zh_TW/templates.dita b/plugins/kimchi/ui/pages/help/zh_TW/templates.dita similarity index 100% rename from ui/pages/help/zh_TW/templates.dita rename to plugins/kimchi/ui/pages/help/zh_TW/templates.dita diff --git a/ui/pages/tabs/host.html.tmpl b/plugins/kimchi/ui/pages/host.html.tmpl similarity index 97% rename from ui/pages/tabs/host.html.tmpl rename to plugins/kimchi/ui/pages/host.html.tmpl index c4bf7f0c4..d87debc34 100644 --- a/ui/pages/tabs/host.html.tmpl +++ b/plugins/kimchi/ui/pages/host.html.tmpl @@ -18,10 +18,17 @@ #unicode UTF-8 #import gettext -#from kimchi.cachebust import href +#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 + + + + + + +
@@ -166,3 +173,5 @@ + + diff --git a/plugins/kimchi/ui/pages/i18n.json.tmpl b/plugins/kimchi/ui/pages/i18n.json.tmpl new file mode 100644 index 000000000..cd320e0e1 --- /dev/null +++ b/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/ui/pages/tabs/network.html.tmpl b/plugins/kimchi/ui/pages/network.html.tmpl similarity index 97% rename from ui/pages/tabs/network.html.tmpl rename to plugins/kimchi/ui/pages/network.html.tmpl index e2b16399d..915feac1b 100644 --- a/ui/pages/tabs/network.html.tmpl +++ b/plugins/kimchi/ui/pages/network.html.tmpl @@ -18,12 +18,16 @@ #unicode UTF-8 #import gettext -#from kimchi.cachebust import href +#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 + + + +