123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664 |
- # -*- coding: utf-8 -*-
- '''
- virt execution module unit tests
- '''
- # pylint: disable=3rd-party-module-not-gated
- # Import python libs
- from __future__ import absolute_import, print_function, unicode_literals
- import os
- import re
- import datetime
- # Import Salt Testing libs
- from tests.support.mixins import LoaderModuleMockMixin
- from tests.support.unit import TestCase
- from tests.support.mock import MagicMock, patch
- # Import salt libs
- import salt.utils.yaml
- import salt.modules.virt as virt
- import salt.modules.config as config
- from salt._compat import ElementTree as ET
- import salt.config
- import salt.syspaths
- from salt.exceptions import CommandExecutionError
- # Import third party libs
- from salt.ext import six
- # pylint: disable=import-error
- from salt.ext.six.moves import range # pylint: disable=redefined-builtin
- # pylint: disable=invalid-name,protected-access,attribute-defined-outside-init,too-many-public-methods,unused-argument
- class LibvirtMock(MagicMock): # pylint: disable=too-many-ancestors
- '''
- Libvirt library mock
- '''
- class virDomain(MagicMock):
- '''
- virDomain mock
- '''
- class libvirtError(Exception):
- '''
- libvirtError mock
- '''
- class VirtTestCase(TestCase, LoaderModuleMockMixin):
- '''
- Test cases for salt.module.virt
- '''
- def setup_loader_modules(self):
- self.mock_libvirt = LibvirtMock()
- self.mock_conn = MagicMock()
- self.mock_libvirt.openAuth.return_value = self.mock_conn
- self.mock_popen = MagicMock()
- self.addCleanup(delattr, self, 'mock_libvirt')
- self.addCleanup(delattr, self, 'mock_conn')
- self.addCleanup(delattr, self, 'mock_popen')
- mock_subprocess = MagicMock()
- mock_subprocess.Popen.return_value = self.mock_popen # pylint: disable=no-member
- loader_globals = {
- '__salt__': {
- 'config.get': config.get,
- 'config.option': config.option,
- },
- 'libvirt': self.mock_libvirt,
- 'subprocess': mock_subprocess
- }
- return {virt: loader_globals, config: loader_globals}
- def set_mock_vm(self, name, xml):
- '''
- Define VM to use in tests
- '''
- self.mock_conn.listDefinedDomains.return_value = [name] # pylint: disable=no-member
- mock_domain = self.mock_libvirt.virDomain()
- self.mock_conn.lookupByName.return_value = mock_domain # pylint: disable=no-member
- mock_domain.XMLDesc.return_value = xml # pylint: disable=no-member
- # Return state as shutdown
- mock_domain.info.return_value = [4, 0, 0, 0] # pylint: disable=no-member
- return mock_domain
- def test_disk_profile_merge(self):
- '''
- Test virt._disk_profile() when merging with user-defined disks
- '''
- root_dir = os.path.join(salt.syspaths.ROOT_DIR, 'srv', 'salt-images')
- userdisks = [{'name': 'data', 'size': 16384, 'format': 'raw'}]
- disks = virt._disk_profile('default', 'kvm', userdisks, 'myvm', image='/path/to/image')
- self.assertEqual(
- [{'name': 'system',
- 'device': 'disk',
- 'size': 8192,
- 'format': 'qcow2',
- 'model': 'virtio',
- 'filename': 'myvm_system.qcow2',
- 'image': '/path/to/image',
- 'source_file': '{0}{1}myvm_system.qcow2'.format(root_dir, os.sep)},
- {'name': 'data',
- 'device': 'disk',
- 'size': 16384,
- 'format': 'raw',
- 'model': 'virtio',
- 'filename': 'myvm_data.raw',
- 'source_file': '{0}{1}myvm_data.raw'.format(root_dir, os.sep)}],
- disks
- )
- def test_boot_default_dev(self):
- '''
- Test virt._gen_xml() default boot device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64'
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('os/boot').attrib['dev'], 'hd')
- self.assertEqual(root.find('os/type').attrib['arch'], 'x86_64')
- self.assertEqual(root.find('os/type').text, 'hvm')
- def test_boot_custom_dev(self):
- '''
- Test virt._gen_xml() custom boot device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- boot_dev='cdrom'
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('os/boot').attrib['dev'], 'cdrom')
- def test_boot_multiple_devs(self):
- '''
- Test virt._gen_xml() multiple boot devices
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- boot_dev='cdrom network'
- )
- root = ET.fromstring(xml_data)
- devs = root.findall('.//boot')
- self.assertTrue(len(devs) == 2)
- def test_gen_xml_no_nic(self):
- '''
- Test virt._gen_xml() serial console
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='pty',
- console=True
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'pty')
- self.assertEqual(root.find('devices/console').attrib['type'], 'pty')
- def test_gen_xml_for_serial_console(self):
- '''
- Test virt._gen_xml() serial console
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='pty',
- console=True
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'pty')
- self.assertEqual(root.find('devices/console').attrib['type'], 'pty')
- def test_gen_xml_for_telnet_console(self):
- '''
- Test virt._gen_xml() telnet console
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='tcp',
- console=True,
- telnet_port=22223
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'tcp')
- self.assertEqual(root.find('devices/console').attrib['type'], 'tcp')
- self.assertEqual(root.find('devices/console/source').attrib['service'], '22223')
- def test_gen_xml_for_telnet_console_unspecified_port(self):
- '''
- Test virt._gen_xml() telnet console without any specified port
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='tcp',
- console=True
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'tcp')
- self.assertEqual(root.find('devices/console').attrib['type'], 'tcp')
- self.assertIsInstance(int(root.find('devices/console/source').attrib['service']), int)
- def test_gen_xml_for_serial_no_console(self):
- '''
- Test virt._gen_xml() with no serial console
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='pty',
- console=False
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'pty')
- self.assertEqual(root.find('devices/console'), None)
- def test_gen_xml_for_telnet_no_console(self):
- '''
- Test virt._gen_xml() with no telnet console
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- serial_type='tcp',
- console=False,
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/serial').attrib['type'], 'tcp')
- self.assertEqual(root.find('devices/console'), None)
- def test_gen_xml_nographics_default(self):
- '''
- Test virt._gen_xml() with default no graphics device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64'
- )
- root = ET.fromstring(xml_data)
- self.assertIsNone(root.find('devices/graphics'))
- def test_gen_xml_vnc_default(self):
- '''
- Test virt._gen_xml() with default vnc graphics device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- graphics={'type': 'vnc', 'port': 1234, 'tlsPort': 5678,
- 'listen': {'type': 'address', 'address': 'myhost'}},
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/graphics').attrib['type'], 'vnc')
- self.assertEqual(root.find('devices/graphics').attrib['autoport'], 'no')
- self.assertEqual(root.find('devices/graphics').attrib['port'], '1234')
- self.assertFalse('tlsPort' in root.find('devices/graphics').attrib)
- self.assertEqual(root.find('devices/graphics').attrib['listen'], 'myhost')
- self.assertEqual(root.find('devices/graphics/listen').attrib['type'], 'address')
- self.assertEqual(root.find('devices/graphics/listen').attrib['address'], 'myhost')
- def test_gen_xml_spice_default(self):
- '''
- Test virt._gen_xml() with default spice graphics device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- graphics={'type': 'spice'},
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/graphics').attrib['type'], 'spice')
- self.assertEqual(root.find('devices/graphics').attrib['autoport'], 'yes')
- self.assertEqual(root.find('devices/graphics').attrib['listen'], '0.0.0.0')
- self.assertEqual(root.find('devices/graphics/listen').attrib['type'], 'address')
- self.assertEqual(root.find('devices/graphics/listen').attrib['address'], '0.0.0.0')
- def test_gen_xml_spice(self):
- '''
- Test virt._gen_xml() with spice graphics device
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- graphics={'type': 'spice', 'port': 1234, 'tls_port': 5678, 'listen': {'type': 'none'}},
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('devices/graphics').attrib['type'], 'spice')
- self.assertEqual(root.find('devices/graphics').attrib['autoport'], 'no')
- self.assertEqual(root.find('devices/graphics').attrib['port'], '1234')
- self.assertEqual(root.find('devices/graphics').attrib['tlsPort'], '5678')
- self.assertFalse('listen' in root.find('devices/graphics').attrib)
- self.assertEqual(root.find('devices/graphics/listen').attrib['type'], 'none')
- self.assertFalse('address' in root.find('devices/graphics/listen').attrib)
- def test_default_disk_profile_hypervisor_esxi(self):
- '''
- Test virt._disk_profile() default ESXi profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._disk_profile('nonexistent', 'vmware')
- self.assertTrue(len(ret) == 1)
- found = [disk for disk in ret if disk['name'] == 'system']
- self.assertTrue(bool(found))
- system = found[0]
- self.assertEqual(system['format'], 'vmdk')
- self.assertEqual(system['model'], 'scsi')
- self.assertTrue(int(system['size']) >= 1)
- def test_default_disk_profile_hypervisor_kvm(self):
- '''
- Test virt._disk_profile() default KVM profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._disk_profile('nonexistent', 'kvm')
- self.assertTrue(len(ret) == 1)
- found = [disk for disk in ret if disk['name'] == 'system']
- self.assertTrue(bool(found))
- system = found[0]
- self.assertEqual(system['format'], 'qcow2')
- self.assertEqual(system['model'], 'virtio')
- self.assertTrue(int(system['size']) >= 1)
- def test_default_disk_profile_hypervisor_xen(self):
- '''
- Test virt._disk_profile() default XEN profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._disk_profile('nonexistent', 'xen')
- self.assertTrue(len(ret) == 1)
- found = [disk for disk in ret if disk['name'] == 'system']
- self.assertTrue(bool(found))
- system = found[0]
- self.assertEqual(system['format'], 'qcow2')
- self.assertEqual(system['model'], 'xen')
- self.assertTrue(int(system['size']) >= 1)
- def test_default_nic_profile_hypervisor_esxi(self):
- '''
- Test virt._nic_profile() default ESXi profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._nic_profile('nonexistent', 'vmware')
- self.assertTrue(len(ret) == 1)
- eth0 = ret[0]
- self.assertEqual(eth0['name'], 'eth0')
- self.assertEqual(eth0['type'], 'bridge')
- self.assertEqual(eth0['source'], 'DEFAULT')
- self.assertEqual(eth0['model'], 'e1000')
- def test_default_nic_profile_hypervisor_kvm(self):
- '''
- Test virt._nic_profile() default KVM profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._nic_profile('nonexistent', 'kvm')
- self.assertTrue(len(ret) == 1)
- eth0 = ret[0]
- self.assertEqual(eth0['name'], 'eth0')
- self.assertEqual(eth0['type'], 'bridge')
- self.assertEqual(eth0['source'], 'br0')
- self.assertEqual(eth0['model'], 'virtio')
- def test_default_nic_profile_hypervisor_xen(self):
- '''
- Test virt._nic_profile() default XEN profile
- '''
- mock = MagicMock(return_value={})
- with patch.dict(virt.__salt__, {'config.get': mock}): # pylint: disable=no-member
- ret = virt._nic_profile('nonexistent', 'xen')
- self.assertTrue(len(ret) == 1)
- eth0 = ret[0]
- self.assertEqual(eth0['name'], 'eth0')
- self.assertEqual(eth0['type'], 'bridge')
- self.assertEqual(eth0['source'], 'br0')
- self.assertFalse(eth0['model'])
- def test_gen_vol_xml(self):
- '''
- Test virt._get_vol_xml()
- '''
- xml_data = virt._gen_vol_xml('vmname', 'system', 'qcow2', 8192, '/path/to/image/')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'vmname/system.qcow2')
- self.assertEqual(root.find('key').text, 'vmname/system')
- self.assertEqual(root.find('capacity').attrib['unit'], 'KiB')
- self.assertEqual(root.find('capacity').text, six.text_type(8192 * 1024))
- def test_gen_xml_for_kvm_default_profile(self):
- '''
- Test virt._gen_xml(), KVM default profile case
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.attrib['type'], 'kvm')
- self.assertEqual(root.find('vcpu').text, '1')
- self.assertEqual(root.find('memory').text, six.text_type(512 * 1024))
- self.assertEqual(root.find('memory').attrib['unit'], 'KiB')
- disks = root.findall('.//disk')
- self.assertEqual(len(disks), 1)
- disk = disks[0]
- root_dir = salt.config.DEFAULT_MINION_OPTS.get('root_dir')
- self.assertTrue(disk.find('source').attrib['file'].startswith(root_dir))
- self.assertTrue('hello_system' in disk.find('source').attrib['file'])
- self.assertEqual(disk.find('target').attrib['dev'], 'vda')
- self.assertEqual(disk.find('target').attrib['bus'], 'virtio')
- self.assertEqual(disk.find('driver').attrib['name'], 'qemu')
- self.assertEqual(disk.find('driver').attrib['type'], 'qcow2')
- interfaces = root.findall('.//interface')
- self.assertEqual(len(interfaces), 1)
- iface = interfaces[0]
- self.assertEqual(iface.attrib['type'], 'bridge')
- self.assertEqual(iface.find('source').attrib['bridge'], 'br0')
- self.assertEqual(iface.find('model').attrib['type'], 'virtio')
- mac = iface.find('mac').attrib['address']
- self.assertTrue(
- re.match('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$', mac, re.I))
- def test_gen_xml_for_esxi_default_profile(self):
- '''
- Test virt._gen_xml(), ESXi/vmware default profile case
- '''
- diskp = virt._disk_profile('default', 'vmware', [], 'hello')
- nicp = virt._nic_profile('default', 'vmware')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'vmware',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.attrib['type'], 'vmware')
- self.assertEqual(root.find('vcpu').text, '1')
- self.assertEqual(root.find('memory').text, six.text_type(512 * 1024))
- self.assertEqual(root.find('memory').attrib['unit'], 'KiB')
- disks = root.findall('.//disk')
- self.assertEqual(len(disks), 1)
- disk = disks[0]
- self.assertTrue('[0]' in disk.find('source').attrib['file'])
- self.assertTrue('hello_system' in disk.find('source').attrib['file'])
- self.assertEqual(disk.find('target').attrib['dev'], 'sda')
- self.assertEqual(disk.find('target').attrib['bus'], 'scsi')
- self.assertEqual(disk.find('address').attrib['unit'], '0')
- interfaces = root.findall('.//interface')
- self.assertEqual(len(interfaces), 1)
- iface = interfaces[0]
- self.assertEqual(iface.attrib['type'], 'bridge')
- self.assertEqual(iface.find('source').attrib['bridge'], 'DEFAULT')
- self.assertEqual(iface.find('model').attrib['type'], 'e1000')
- mac = iface.find('mac').attrib['address']
- self.assertTrue(
- re.match('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$', mac, re.I))
- def test_gen_xml_for_xen_default_profile(self):
- '''
- Test virt._gen_xml(), XEN PV default profile case
- '''
- diskp = virt._disk_profile('default', 'xen', [], 'hello')
- nicp = virt._nic_profile('default', 'xen')
- with patch.dict(virt.__grains__, {'os_family': 'Suse'}):
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'xen',
- 'xen',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.attrib['type'], 'xen')
- self.assertEqual(root.find('vcpu').text, '1')
- self.assertEqual(root.find('memory').text, six.text_type(512 * 1024))
- self.assertEqual(root.find('memory').attrib['unit'], 'KiB')
- self.assertEqual(root.find('.//kernel').text, '/usr/lib/grub2/x86_64-xen/grub.xen')
- disks = root.findall('.//disk')
- self.assertEqual(len(disks), 1)
- disk = disks[0]
- root_dir = salt.config.DEFAULT_MINION_OPTS.get('root_dir')
- self.assertTrue(disk.find('source').attrib['file'].startswith(root_dir))
- self.assertTrue('hello_system' in disk.find('source').attrib['file'])
- self.assertEqual(disk.find('target').attrib['dev'], 'xvda')
- self.assertEqual(disk.find('target').attrib['bus'], 'xen')
- self.assertEqual(disk.find('driver').attrib['name'], 'qemu')
- self.assertEqual(disk.find('driver').attrib['type'], 'qcow2')
- interfaces = root.findall('.//interface')
- self.assertEqual(len(interfaces), 1)
- iface = interfaces[0]
- self.assertEqual(iface.attrib['type'], 'bridge')
- self.assertEqual(iface.find('source').attrib['bridge'], 'br0')
- self.assertIsNone(iface.find('model'))
- def test_gen_xml_for_esxi_custom_profile(self):
- '''
- Test virt._gen_xml(), ESXi/vmware custom profile case
- '''
- disks = {
- 'noeffect': [
- {'first': {'size': 8192, 'pool': 'datastore1'}},
- {'second': {'size': 4096, 'pool': 'datastore2'}}
- ]
- }
- nics = {
- 'noeffect': [
- {'name': 'eth1', 'source': 'ONENET'},
- {'name': 'eth2', 'source': 'TWONET'}
- ]
- }
- with patch.dict(virt.__salt__, # pylint: disable=no-member
- {'config.get': MagicMock(side_effect=[disks, nics])}):
- diskp = virt._disk_profile('noeffect', 'vmware', [], 'hello')
- nicp = virt._nic_profile('noeffect', 'vmware')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'vmware',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.attrib['type'], 'vmware')
- self.assertEqual(root.find('vcpu').text, '1')
- self.assertEqual(root.find('memory').text, six.text_type(512 * 1024))
- self.assertEqual(root.find('memory').attrib['unit'], 'KiB')
- self.assertTrue(len(root.findall('.//disk')) == 2)
- self.assertTrue(len(root.findall('.//interface')) == 2)
- def test_gen_xml_for_kvm_custom_profile(self):
- '''
- Test virt._gen_xml(), KVM custom profile case
- '''
- disks = {
- 'noeffect': [
- {'first': {'size': 8192, 'pool': '/var/lib/images'}},
- {'second': {'size': 4096, 'pool': '/var/lib/images'}}
- ]
- }
- nics = {
- 'noeffect': [
- {'name': 'eth1', 'source': 'b2'},
- {'name': 'eth2', 'source': 'b2'}
- ]
- }
- with patch.dict(virt.__salt__, {'config.get': MagicMock(side_effect=[ # pylint: disable=no-member
- disks, nics])}):
- diskp = virt._disk_profile('noeffect', 'kvm', [], 'hello')
- nicp = virt._nic_profile('noeffect', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.attrib['type'], 'kvm')
- self.assertEqual(root.find('vcpu').text, '1')
- self.assertEqual(root.find('memory').text, six.text_type(512 * 1024))
- self.assertEqual(root.find('memory').attrib['unit'], 'KiB')
- self.assertTrue(len(root.findall('.//disk')) == 2)
- self.assertTrue(len(root.findall('.//interface')) == 2)
- @patch('salt.modules.virt.pool_info',
- return_value={'mypool': {'target_path': os.path.join(salt.syspaths.ROOT_DIR, 'pools', 'mypool')}})
- def test_disk_profile_kvm_disk_pool(self, mock_poolinfo):
- '''
- Test virt._gen_xml(), KVM case with pools defined.
- '''
- disks = {
- 'noeffect': [
- {'first': {'size': 8192, 'pool': 'mypool'}},
- {'second': {'size': 4096}}
- ]
- }
- # pylint: disable=no-member
- with patch.dict(virt.__salt__, {'config.get': MagicMock(side_effect=[
- disks,
- os.path.join(salt.syspaths.ROOT_DIR, 'default', 'path')])}):
- diskp = virt._disk_profile('noeffect', 'kvm', [], 'hello')
- pools_path = os.path.join(salt.syspaths.ROOT_DIR, 'pools', 'mypool') + os.sep
- default_path = os.path.join(salt.syspaths.ROOT_DIR, 'default', 'path') + os.sep
- self.assertEqual(len(diskp), 2)
- self.assertTrue(diskp[0]['source_file'].startswith(pools_path))
- self.assertTrue(diskp[1]['source_file'].startswith(default_path))
- # pylint: enable=no-member
- def test_disk_profile_kvm_disk_external_image(self):
- '''
- Test virt._gen_xml(), KVM case with an external image.
- '''
- diskp = virt._disk_profile(None, 'kvm', [
- {
- 'name': 'mydisk',
- 'source_file': '/path/to/my/image.qcow2'
- }], 'hello')
- self.assertEqual(len(diskp), 1)
- self.assertEqual(diskp[0]['source_file'], ('/path/to/my/image.qcow2'))
- @patch('salt.modules.virt.pool_info', return_value={})
- def test_disk_profile_kvm_disk_pool_notfound(self, mock_poolinfo):
- '''
- Test virt._gen_xml(), KVM case with pools defined.
- '''
- disks = {
- 'noeffect': [
- {'first': {'size': 8192, 'pool': 'default'}},
- ]
- }
- with patch.dict(virt.__salt__, {'config.get': MagicMock(side_effect=[ # pylint: disable=no-member
- disks, "/default/path/"])}):
- with self.assertRaises(CommandExecutionError):
- virt._disk_profile('noeffect', 'kvm', [], 'hello')
- @patch('salt.modules.virt.pool_info', return_value={'target_path': '/dev/disk/by-path'})
- def test_disk_profile_kvm_disk_pool_invalid(self, mock_poolinfo):
- '''
- Test virt._gen_xml(), KVM case with pools defined.
- '''
- disks = {
- 'noeffect': [
- {'first': {'size': 8192, 'pool': 'default'}},
- ]
- }
- with patch.dict(virt.__salt__, {'config.get': MagicMock(side_effect=[ # pylint: disable=no-member
- disks, "/default/path/"])}):
- with self.assertRaises(CommandExecutionError):
- virt._disk_profile('noeffect', 'kvm', [], 'hello')
- def test_gen_xml_cdrom(self):
- '''
- Test virt._gen_xml(), generating a cdrom device (different disk type, no source)
- '''
- diskp = virt._disk_profile(None, 'kvm', [{
- 'name': 'tested',
- 'device': 'cdrom',
- 'source_file': None,
- 'model': 'ide'}], 'hello')
- nicp = virt._nic_profile(None, 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- disk = root.findall('.//disk')[0]
- self.assertEqual(disk.attrib['device'], 'cdrom')
- self.assertIsNone(disk.find('source'))
- def test_controller_for_esxi(self):
- '''
- Test virt._gen_xml() generated device controller for ESXi/vmware
- '''
- diskp = virt._disk_profile('default', 'vmware', [], 'hello')
- nicp = virt._nic_profile('default', 'vmware')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'vmware',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- controllers = root.findall('.//devices/controller')
- self.assertTrue(len(controllers) == 1)
- controller = controllers[0]
- self.assertEqual(controller.attrib['model'], 'lsilogic')
- def test_controller_for_kvm(self):
- '''
- Test virt._gen_xml() generated device controller for KVM
- '''
- diskp = virt._disk_profile('default', 'kvm', [], 'hello')
- nicp = virt._nic_profile('default', 'kvm')
- xml_data = virt._gen_xml(
- 'hello',
- 1,
- 512,
- diskp,
- nicp,
- 'kvm',
- 'hvm',
- 'x86_64',
- )
- root = ET.fromstring(xml_data)
- controllers = root.findall('.//devices/controller')
- # There should be no controller
- self.assertTrue(len(controllers) == 0)
- # kvm mac address shoud start with 52:54:00
- self.assertTrue("mac address='52:54:00" in xml_data)
- def test_diff_disks(self):
- '''
- Test virt._diff_disks()
- '''
- old_disks = ET.fromstring('''
- <devices>
- <disk type='file' device='disk'>
- <source file='/path/to/img0.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='disk'>
- <source file='/path/to/img1.qcow2'/>
- <target dev='vdb' bus='virtio'/>
- </disk>
- <disk type='file' device='disk'>
- <source file='/path/to/img2.qcow2'/>
- <target dev='hda' bus='ide'/>
- </disk>
- <disk type='file' device='disk'>
- <source file='/path/to/img4.qcow2'/>
- <target dev='hdb' bus='ide'/>
- </disk>
- <disk type='file' device='cdrom'>
- <target dev='hdc' bus='ide'/>
- </disk>
- </devices>
- ''').findall('disk')
- new_disks = ET.fromstring('''
- <devices>
- <disk type='file' device='disk'>
- <source file='/path/to/img3.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='disk' cache='default'>
- <source file='/path/to/img0.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='disk'>
- <source file='/path/to/img4.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='cdrom'>
- <target dev='hda' bus='ide'/>
- </disk>
- </devices>
- ''').findall('disk')
- ret = virt._diff_disk_lists(old_disks, new_disks)
- self.assertEqual([disk.find('source').get('file') if disk.find('source') is not None else None
- for disk in ret['unchanged']], [])
- self.assertEqual([disk.find('source').get('file') if disk.find('source') is not None else None
- for disk in ret['new']],
- ['/path/to/img3.qcow2', '/path/to/img0.qcow2', '/path/to/img4.qcow2', None])
- self.assertEqual([disk.find('target').get('dev') for disk in ret['sorted']],
- ['vda', 'vdb', 'vdc', 'hda'])
- self.assertEqual([disk.find('source').get('file') if disk.find('source') is not None else None
- for disk in ret['sorted']],
- ['/path/to/img3.qcow2',
- '/path/to/img0.qcow2',
- '/path/to/img4.qcow2',
- None])
- self.assertEqual(ret['new'][1].find('target').get('bus'), 'virtio')
- self.assertEqual([disk.find('source').get('file') if disk.find('source') is not None else None
- for disk in ret['deleted']],
- ['/path/to/img0.qcow2',
- '/path/to/img1.qcow2',
- '/path/to/img2.qcow2',
- '/path/to/img4.qcow2',
- None])
- def test_diff_nics(self):
- '''
- Test virt._diff_nics()
- '''
- old_nics = ET.fromstring('''
- <devices>
- <interface type='network'>
- <mac address='52:54:00:39:02:b1'/>
- <source network='default'/>
- <model type='virtio'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </interface>
- <interface type='network'>
- <mac address='52:54:00:39:02:b2'/>
- <source network='admin'/>
- <model type='virtio'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </interface>
- <interface type='network'>
- <mac address='52:54:00:39:02:b3'/>
- <source network='admin'/>
- <model type='virtio'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </interface>
- </devices>
- ''').findall('interface')
- new_nics = ET.fromstring('''
- <devices>
- <interface type='network'>
- <mac address='52:54:00:39:02:b1'/>
- <source network='default'/>
- <model type='virtio'/>
- </interface>
- <interface type='network'>
- <mac address='52:54:00:39:02:b2'/>
- <source network='default'/>
- <model type='virtio'/>
- </interface>
- <interface type='network'>
- <mac address='52:54:00:39:02:b4'/>
- <source network='admin'/>
- <model type='virtio'/>
- </interface>
- </devices>
- ''').findall('interface')
- ret = virt._diff_interface_lists(old_nics, new_nics)
- self.assertEqual([nic.find('mac').get('address') for nic in ret['unchanged']],
- ['52:54:00:39:02:b1'])
- self.assertEqual([nic.find('mac').get('address') for nic in ret['new']],
- ['52:54:00:39:02:b2', '52:54:00:39:02:b4'])
- self.assertEqual([nic.find('mac').get('address') for nic in ret['deleted']],
- ['52:54:00:39:02:b2', '52:54:00:39:02:b3'])
- def test_init(self):
- '''
- Test init() function
- '''
- xml = '''
- <capabilities>
- <host>
- <uuid>44454c4c-3400-105a-8033-b3c04f4b344a</uuid>
- <cpu>
- <arch>x86_64</arch>
- <model>Nehalem</model>
- <vendor>Intel</vendor>
- <microcode version='25'/>
- <topology sockets='1' cores='4' threads='2'/>
- <feature name='vme'/>
- <feature name='ds'/>
- <feature name='acpi'/>
- <pages unit='KiB' size='4'/>
- <pages unit='KiB' size='2048'/>
- </cpu>
- <power_management>
- <suspend_mem/>
- <suspend_disk/>
- <suspend_hybrid/>
- </power_management>
- <migration_features>
- <live/>
- <uri_transports>
- <uri_transport>tcp</uri_transport>
- <uri_transport>rdma</uri_transport>
- </uri_transports>
- </migration_features>
- <topology>
- <cells num='1'>
- <cell id='0'>
- <memory unit='KiB'>12367120</memory>
- <pages unit='KiB' size='4'>3091780</pages>
- <pages unit='KiB' size='2048'>0</pages>
- <distances>
- <sibling id='0' value='10'/>
- </distances>
- <cpus num='8'>
- <cpu id='0' socket_id='0' core_id='0' siblings='0,4'/>
- <cpu id='1' socket_id='0' core_id='1' siblings='1,5'/>
- <cpu id='2' socket_id='0' core_id='2' siblings='2,6'/>
- <cpu id='3' socket_id='0' core_id='3' siblings='3,7'/>
- <cpu id='4' socket_id='0' core_id='0' siblings='0,4'/>
- <cpu id='5' socket_id='0' core_id='1' siblings='1,5'/>
- <cpu id='6' socket_id='0' core_id='2' siblings='2,6'/>
- <cpu id='7' socket_id='0' core_id='3' siblings='3,7'/>
- </cpus>
- </cell>
- </cells>
- </topology>
- <cache>
- <bank id='0' level='3' type='both' size='8' unit='MiB' cpus='0-7'/>
- </cache>
- <secmodel>
- <model>apparmor</model>
- <doi>0</doi>
- </secmodel>
- <secmodel>
- <model>dac</model>
- <doi>0</doi>
- <baselabel type='kvm'>+487:+486</baselabel>
- <baselabel type='qemu'>+487:+486</baselabel>
- </secmodel>
- </host>
- <guest>
- <os_type>hvm</os_type>
- <arch name='i686'>
- <wordsize>32</wordsize>
- <emulator>/usr/bin/qemu-system-i386</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- <domain type='qemu'/>
- <domain type='kvm'>
- <emulator>/usr/bin/qemu-kvm</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- </domain>
- </arch>
- <features>
- <cpuselection/>
- <deviceboot/>
- <disksnapshot default='on' toggle='no'/>
- <acpi default='on' toggle='yes'/>
- <apic default='on' toggle='no'/>
- <pae/>
- <nonpae/>
- </features>
- </guest>
- <guest>
- <os_type>hvm</os_type>
- <arch name='x86_64'>
- <wordsize>64</wordsize>
- <emulator>/usr/bin/qemu-system-x86_64</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- <domain type='qemu'/>
- <domain type='kvm'>
- <emulator>/usr/bin/qemu-kvm</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- </domain>
- </arch>
- <features>
- <cpuselection/>
- <deviceboot/>
- <disksnapshot default='on' toggle='no'/>
- <acpi default='on' toggle='yes'/>
- <apic default='on' toggle='no'/>
- </features>
- </guest>
- </capabilities>
- '''
- self.mock_conn.getCapabilities.return_value = xml # pylint: disable=no-member
- root_dir = os.path.join(salt.syspaths.ROOT_DIR, 'srv', 'salt-images')
- defineMock = MagicMock(return_value=1)
- self.mock_conn.defineXML = defineMock
- mock_chmod = MagicMock()
- mock_run = MagicMock()
- with patch.dict(os.__dict__, {'chmod': mock_chmod, 'makedirs': MagicMock()}): # pylint: disable=no-member
- with patch.dict(virt.__salt__, {'cmd.run': mock_run}): # pylint: disable=no-member
- # Ensure the init() function allows creating VM without NIC and disk
- virt.init('test vm',
- 2,
- 1234,
- nic=None,
- disk=None,
- seed=False,
- start=False)
- definition = defineMock.call_args_list[0][0][0]
- self.assertFalse('<interface' in definition)
- self.assertFalse('<disk' in definition)
- # Test case creating disks
- defineMock.reset_mock()
- mock_run.reset_mock()
- virt.init('test vm',
- 2,
- 1234,
- nic=None,
- disk=None,
- disks=[
- {'name': 'system', 'size': 10240},
- {'name': 'cddrive', 'device': 'cdrom', 'source_file': None, 'model': 'ide'}
- ],
- seed=False,
- start=False)
- definition = ET.fromstring(defineMock.call_args_list[0][0][0])
- disk_sources = [disk.find('source').get('file') if disk.find('source') is not None else None
- for disk in definition.findall('./devices/disk')]
- expected_disk_path = os.path.join(root_dir, 'test vm_system.qcow2')
- self.assertEqual(disk_sources, [expected_disk_path, None])
- self.assertEqual(mock_run.call_args[0][0],
- 'qemu-img create -f qcow2 "{0}" 10240M'.format(expected_disk_path))
- self.assertEqual(mock_chmod.call_args[0][0], expected_disk_path)
- def test_update(self):
- '''
- Test virt.update()
- '''
- root_dir = os.path.join(salt.syspaths.ROOT_DIR, 'srv', 'salt-images')
- xml = '''
- <domain type='kvm' id='7'>
- <name>my vm</name>
- <memory unit='KiB'>1048576</memory>
- <currentMemory unit='KiB'>1048576</currentMemory>
- <vcpu placement='auto'>1</vcpu>
- <os>
- <type arch='x86_64' machine='pc-i440fx-2.6'>hvm</type>
- </os>
- <devices>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2'/>
- <source file='{0}{1}my vm_system.qcow2'/>
- <backingStore/>
- <target dev='vda' bus='virtio'/>
- <alias name='virtio-disk0'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
- </disk>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2'/>
- <source file='{0}{1}my vm_data.qcow2'/>
- <backingStore/>
- <target dev='vdb' bus='virtio'/>
- <alias name='virtio-disk1'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x1'/>
- </disk>
- <interface type='network'>
- <mac address='52:54:00:39:02:b1'/>
- <source network='default' bridge='virbr0'/>
- <target dev='vnet0'/>
- <model type='virtio'/>
- <alias name='net0'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </interface>
- <interface type='network'>
- <mac address='52:54:00:39:02:b2'/>
- <source network='oldnet' bridge='virbr1'/>
- <target dev='vnet1'/>
- <model type='virtio'/>
- <alias name='net1'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
- </interface>
- <graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'>
- <listen type='address' address='127.0.0.1'/>
- </graphics>
- <video>
- <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
- <alias name='video0'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
- </video>
- </devices>
- </domain>
- '''.format(root_dir, os.sep)
- domain_mock = self.set_mock_vm('my vm', xml)
- domain_mock.OSType = MagicMock(return_value='hvm')
- define_mock = MagicMock(return_value=True)
- self.mock_conn.defineXML = define_mock
- # Update vcpus case
- setvcpus_mock = MagicMock(return_value=0)
- domain_mock.setVcpusFlags = setvcpus_mock
- self.assertEqual({
- 'definition': True,
- 'cpu': True,
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', cpu=2))
- setxml = ET.fromstring(define_mock.call_args[0][0])
- self.assertEqual(setxml.find('vcpu').text, '2')
- self.assertEqual(setvcpus_mock.call_args[0][0], 2)
- # Update memory case
- setmem_mock = MagicMock(return_value=0)
- domain_mock.setMemoryFlags = setmem_mock
- self.assertEqual({
- 'definition': True,
- 'mem': True,
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', mem=2048))
- setxml = ET.fromstring(define_mock.call_args[0][0])
- self.assertEqual(setxml.find('memory').text, '2048')
- self.assertEqual(setxml.find('memory').get('unit'), 'MiB')
- self.assertEqual(setmem_mock.call_args[0][0], 2048 * 1024)
- # Update disks case
- devattach_mock = MagicMock(return_value=0)
- devdetach_mock = MagicMock(return_value=0)
- domain_mock.attachDevice = devattach_mock
- domain_mock.detachDevice = devdetach_mock
- mock_chmod = MagicMock()
- mock_run = MagicMock()
- with patch.dict(os.__dict__, {'chmod': mock_chmod, 'makedirs': MagicMock()}): # pylint: disable=no-member
- with patch.dict(virt.__salt__, {'cmd.run': mock_run}): # pylint: disable=no-member
- ret = virt.update('my vm', disk_profile='default', disks=[
- {'name': 'cddrive', 'device': 'cdrom', 'source_file': None, 'model': 'ide'},
- {'name': 'added', 'size': 2048}])
- added_disk_path = os.path.join(
- virt.__salt__['config.get']('virt:images'), 'my vm_added.qcow2') # pylint: disable=no-member
- self.assertEqual(mock_run.call_args[0][0],
- 'qemu-img create -f qcow2 "{0}" 2048M'.format(added_disk_path))
- self.assertEqual(mock_chmod.call_args[0][0], added_disk_path)
- self.assertListEqual(
- [None, os.path.join(root_dir, 'my vm_added.qcow2')],
- [ET.fromstring(disk).find('source').get('file') if str(disk).find('<source') > -1 else None
- for disk in ret['disk']['attached']])
- self.assertListEqual(
- [os.path.join(root_dir, 'my vm_data.qcow2')],
- [ET.fromstring(disk).find('source').get('file') for disk in ret['disk']['detached']])
- self.assertEqual(devattach_mock.call_count, 2)
- devdetach_mock.assert_called_once()
- # Update nics case
- yaml_config = '''
- virt:
- nic:
- myprofile:
- - network: default
- name: eth0
- '''
- mock_config = salt.utils.yaml.safe_load(yaml_config)
- devattach_mock.reset_mock()
- devdetach_mock.reset_mock()
- with patch.dict(salt.modules.config.__opts__, mock_config): # pylint: disable=no-member
- ret = virt.update('my vm', nic_profile='myprofile',
- interfaces=[{'name': 'eth0', 'type': 'network', 'source': 'default',
- 'mac': '52:54:00:39:02:b1'},
- {'name': 'eth1', 'type': 'network', 'source': 'newnet'}])
- self.assertEqual(['newnet'],
- [ET.fromstring(nic).find('source').get('network') for nic in ret['interface']['attached']])
- self.assertEqual(['oldnet'],
- [ET.fromstring(nic).find('source').get('network') for nic in ret['interface']['detached']])
- devattach_mock.assert_called_once()
- devdetach_mock.assert_called_once()
- # Remove nics case
- devattach_mock.reset_mock()
- devdetach_mock.reset_mock()
- ret = virt.update('my vm', nic_profile=None, interfaces=[])
- self.assertEqual([], ret['interface']['attached'])
- self.assertEqual(2, len(ret['interface']['detached']))
- devattach_mock.assert_not_called()
- devdetach_mock.assert_called()
- # Remove disks case (yeah, it surely is silly)
- devattach_mock.reset_mock()
- devdetach_mock.reset_mock()
- ret = virt.update('my vm', disk_profile=None, disks=[])
- self.assertEqual([], ret['disk']['attached'])
- self.assertEqual(2, len(ret['disk']['detached']))
- devattach_mock.assert_not_called()
- devdetach_mock.assert_called()
- # Graphics change test case
- self.assertEqual({
- 'definition': True,
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', graphics={'type': 'vnc'}))
- setxml = ET.fromstring(define_mock.call_args[0][0])
- self.assertEqual('vnc', setxml.find('devices/graphics').get('type'))
- # Update with no diff case
- self.assertEqual({
- 'definition': False,
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', cpu=1, mem=1024,
- disk_profile='default', disks=[{'name': 'data', 'size': 2048}],
- nic_profile='myprofile',
- interfaces=[{'name': 'eth0', 'type': 'network', 'source': 'default',
- 'mac': '52:54:00:39:02:b1'},
- {'name': 'eth1', 'type': 'network', 'source': 'oldnet',
- 'mac': '52:54:00:39:02:b2'}],
- graphics={'type': 'spice',
- 'listen': {'type': 'address', 'address': '127.0.0.1'}}))
- # Failed XML description update case
- self.mock_conn.defineXML.side_effect = self.mock_libvirt.libvirtError("Test error")
- setmem_mock.reset_mock()
- with self.assertRaises(self.mock_libvirt.libvirtError):
- virt.update('my vm', mem=2048)
- # Failed single update failure case
- self.mock_conn.defineXML = MagicMock(return_value=True)
- setmem_mock.side_effect = self.mock_libvirt.libvirtError("Failed to live change memory")
- self.assertEqual({
- 'definition': True,
- 'errors': ['Failed to live change memory'],
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', mem=2048))
- # Failed multiple updates failure case
- self.assertEqual({
- 'definition': True,
- 'errors': ['Failed to live change memory'],
- 'cpu': True,
- 'disk': {'attached': [], 'detached': []},
- 'interface': {'attached': [], 'detached': []}
- }, virt.update('my vm', cpu=4, mem=2048))
- def test_mixed_dict_and_list_as_profile_objects(self):
- '''
- Test virt._nic_profile with mixed dictionaries and lists as input.
- '''
- yaml_config = '''
- virt:
- nic:
- new-listonly-profile:
- - bridge: br0
- name: eth0
- - model: virtio
- name: eth1
- source: test_network
- type: network
- new-list-with-legacy-names:
- - eth0:
- bridge: br0
- - eth1:
- bridge: br1
- model: virtio
- non-default-legacy-profile:
- eth0:
- bridge: br0
- eth1:
- bridge: br1
- model: virtio
- '''
- mock_config = salt.utils.yaml.safe_load(yaml_config)
- with patch.dict(salt.modules.config.__opts__, mock_config): # pylint: disable=no-member
- for name in six.iterkeys(mock_config['virt']['nic']):
- profile = salt.modules.virt._nic_profile(name, 'kvm')
- self.assertEqual(len(profile), 2)
- interface_attrs = profile[0]
- self.assertIn('source', interface_attrs)
- self.assertIn('type', interface_attrs)
- self.assertIn('name', interface_attrs)
- self.assertIn('model', interface_attrs)
- self.assertEqual(interface_attrs['model'], 'virtio')
- self.assertIn('mac', interface_attrs)
- self.assertTrue(
- re.match('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$',
- interface_attrs['mac'], re.I))
- def test_get_graphics(self):
- '''
- Test virt.get_graphics()
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'>
- <listen type='address' address='0.0.0.0'/>
- </graphics>
- </devices>
- </domain>
- '''
- self.set_mock_vm("test-vm", xml)
- graphics = virt.get_graphics('test-vm')
- self.assertEqual('vnc', graphics['type'])
- self.assertEqual('5900', graphics['port'])
- self.assertEqual('0.0.0.0', graphics['listen'])
- def test_get_nics(self):
- '''
- Test virt.get_nics()
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <interface type='bridge'>
- <mac address='ac:de:48:b6:8b:59'/>
- <source bridge='br0'/>
- <model type='virtio'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
- </interface>
- </devices>
- </domain>
- '''
- self.set_mock_vm("test-vm", xml)
- nics = virt.get_nics('test-vm')
- nic = nics[list(nics)[0]]
- self.assertEqual('bridge', nic['type'])
- self.assertEqual('ac:de:48:b6:8b:59', nic['mac'])
- def test_get_xml(self):
- '''
- Test virt.get_xml()
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'>
- <listen type='address' address='0.0.0.0'/>
- </graphics>
- </devices>
- </domain>
- '''
- domain = self.set_mock_vm("test-vm", xml)
- self.assertEqual(xml, virt.get_xml('test-vm'))
- self.assertEqual(xml, virt.get_xml(domain))
- def test_parse_qemu_img_info(self):
- '''
- Make sure that qemu-img info output is properly parsed
- '''
- qemu_infos = '''[{
- "snapshots": [
- {
- "vm-clock-nsec": 0,
- "name": "first-snap",
- "date-sec": 1528877587,
- "date-nsec": 380589000,
- "vm-clock-sec": 0,
- "id": "1",
- "vm-state-size": 1234
- },
- {
- "vm-clock-nsec": 0,
- "name": "second snap",
- "date-sec": 1528877592,
- "date-nsec": 933509000,
- "vm-clock-sec": 0,
- "id": "2",
- "vm-state-size": 4567
- }
- ],
- "virtual-size": 25769803776,
- "filename": "/disks/test.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 217088,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "full-backing-filename": "/disks/mybacking.qcow2",
- "backing-filename": "mybacking.qcow2",
- "dirty-flag": false
- },
- {
- "virtual-size": 25769803776,
- "filename": "/disks/mybacking.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 393744384,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "full-backing-filename": "/disks/root.qcow2",
- "backing-filename": "root.qcow2",
- "dirty-flag": false
- },
- {
- "virtual-size": 25769803776,
- "filename": "/disks/root.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 196872192,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "dirty-flag": false
- }]'''
- self.assertEqual(
- {
- 'file': '/disks/test.qcow2',
- 'file format': 'qcow2',
- 'backing file': {
- 'file': '/disks/mybacking.qcow2',
- 'file format': 'qcow2',
- 'disk size': 393744384,
- 'virtual size': 25769803776,
- 'cluster size': 65536,
- 'backing file': {
- 'file': '/disks/root.qcow2',
- 'file format': 'qcow2',
- 'disk size': 196872192,
- 'virtual size': 25769803776,
- 'cluster size': 65536,
- }
- },
- 'disk size': 217088,
- 'virtual size': 25769803776,
- 'cluster size': 65536,
- 'snapshots': [
- {
- 'id': '1',
- 'tag': 'first-snap',
- 'vmsize': 1234,
- 'date': datetime.datetime.fromtimestamp(
- float("{}.{}".format(1528877587, 380589000))).isoformat(),
- 'vmclock': '00:00:00'
- },
- {
- 'id': '2',
- 'tag': 'second snap',
- 'vmsize': 4567,
- 'date': datetime.datetime.fromtimestamp(
- float("{}.{}".format(1528877592, 933509000))).isoformat(),
- 'vmclock': '00:00:00'
- }
- ],
- }, virt._parse_qemu_img_info(qemu_infos))
- def test_get_disks(self):
- '''
- Test virt.get_disks()
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2'/>
- <source file='/disks/test.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source file='/disks/test-cdrom.iso'/>
- <target dev='hda' bus='ide'/>
- <readonly/>
- </disk>
- </devices>
- </domain>
- '''
- self.set_mock_vm("test-vm", xml)
- qemu_infos = '''[{
- "virtual-size": 25769803776,
- "filename": "/disks/test.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 217088,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "full-backing-filename": "/disks/mybacking.qcow2",
- "backing-filename": "mybacking.qcow2",
- "dirty-flag": false
- },
- {
- "virtual-size": 25769803776,
- "filename": "/disks/mybacking.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 393744384,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "dirty-flag": false
- }]'''
- self.mock_popen.communicate.return_value = [qemu_infos] # pylint: disable=no-member
- disks = virt.get_disks('test-vm')
- disk = disks.get('vda')
- self.assertEqual('/disks/test.qcow2', disk['file'])
- self.assertEqual('disk', disk['type'])
- self.assertEqual('/disks/mybacking.qcow2', disk['backing file']['file'])
- cdrom = disks.get('hda')
- self.assertEqual('/disks/test-cdrom.iso', cdrom['file'])
- self.assertEqual('cdrom', cdrom['type'])
- self.assertFalse('backing file' in cdrom.keys())
- @patch('salt.modules.virt.stop', return_value=True)
- @patch('salt.modules.virt.undefine')
- @patch('os.remove')
- def test_purge_default(self, mock_remove, mock_undefine, mock_stop):
- '''
- Test virt.purge() with default parameters
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2'/>
- <source file='/disks/test.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source file='/disks/test-cdrom.iso'/>
- <target dev='hda' bus='ide'/>
- <readonly/>
- </disk>
- </devices>
- </domain>
- '''
- self.set_mock_vm("test-vm", xml)
- qemu_infos = '''[{
- "virtual-size": 25769803776,
- "filename": "/disks/test.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 217088,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "dirty-flag": false
- }]'''
- self.mock_popen.communicate.return_value = [qemu_infos] # pylint: disable=no-member
- res = virt.purge('test-vm')
- self.assertTrue(res)
- mock_remove.assert_any_call('/disks/test.qcow2')
- mock_remove.assert_any_call('/disks/test-cdrom.iso')
- @patch('salt.modules.virt.stop', return_value=True)
- @patch('salt.modules.virt.undefine')
- @patch('os.remove')
- def test_purge_noremovable(self, mock_remove, mock_undefine, mock_stop):
- '''
- Test virt.purge(removables=False)
- '''
- xml = '''<domain type='kvm' id='7'>
- <name>test-vm</name>
- <devices>
- <disk type='file' device='disk'>
- <driver name='qemu' type='qcow2'/>
- <source file='/disks/test.qcow2'/>
- <target dev='vda' bus='virtio'/>
- </disk>
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source file='/disks/test-cdrom.iso'/>
- <target dev='hda' bus='ide'/>
- <readonly/>
- </disk>
- <disk type='file' device='floppy'>
- <driver name='qemu' type='raw'/>
- <source file='/disks/test-floppy.iso'/>
- <target dev='hdb' bus='ide'/>
- <readonly/>
- </disk>
- </devices>
- </domain>
- '''
- self.set_mock_vm("test-vm", xml)
- qemu_infos = '''[{
- "virtual-size": 25769803776,
- "filename": "/disks/test.qcow2",
- "cluster-size": 65536,
- "format": "qcow2",
- "actual-size": 217088,
- "format-specific": {
- "type": "qcow2",
- "data": {
- "compat": "1.1",
- "lazy-refcounts": false,
- "refcount-bits": 16,
- "corrupt": false
- }
- },
- "dirty-flag": false
- }]'''
- self.mock_popen.communicate.return_value = [qemu_infos] # pylint: disable=no-member
- res = virt.purge('test-vm', removables=False)
- self.assertTrue(res)
- mock_remove.assert_called_once()
- mock_remove.assert_any_call('/disks/test.qcow2')
- def test_capabilities(self):
- '''
- Test the virt.capabilities parsing
- '''
- xml = '''
- <capabilities>
- <host>
- <uuid>44454c4c-3400-105a-8033-b3c04f4b344a</uuid>
- <cpu>
- <arch>x86_64</arch>
- <model>Nehalem</model>
- <vendor>Intel</vendor>
- <microcode version='25'/>
- <topology sockets='1' cores='4' threads='2'/>
- <feature name='vme'/>
- <feature name='ds'/>
- <feature name='acpi'/>
- <pages unit='KiB' size='4'/>
- <pages unit='KiB' size='2048'/>
- </cpu>
- <power_management>
- <suspend_mem/>
- <suspend_disk/>
- <suspend_hybrid/>
- </power_management>
- <migration_features>
- <live/>
- <uri_transports>
- <uri_transport>tcp</uri_transport>
- <uri_transport>rdma</uri_transport>
- </uri_transports>
- </migration_features>
- <topology>
- <cells num='1'>
- <cell id='0'>
- <memory unit='KiB'>12367120</memory>
- <pages unit='KiB' size='4'>3091780</pages>
- <pages unit='KiB' size='2048'>0</pages>
- <distances>
- <sibling id='0' value='10'/>
- </distances>
- <cpus num='8'>
- <cpu id='0' socket_id='0' core_id='0' siblings='0,4'/>
- <cpu id='1' socket_id='0' core_id='1' siblings='1,5'/>
- <cpu id='2' socket_id='0' core_id='2' siblings='2,6'/>
- <cpu id='3' socket_id='0' core_id='3' siblings='3,7'/>
- <cpu id='4' socket_id='0' core_id='0' siblings='0,4'/>
- <cpu id='5' socket_id='0' core_id='1' siblings='1,5'/>
- <cpu id='6' socket_id='0' core_id='2' siblings='2,6'/>
- <cpu id='7' socket_id='0' core_id='3' siblings='3,7'/>
- </cpus>
- </cell>
- </cells>
- </topology>
- <cache>
- <bank id='0' level='3' type='both' size='8' unit='MiB' cpus='0-7'/>
- </cache>
- <secmodel>
- <model>apparmor</model>
- <doi>0</doi>
- </secmodel>
- <secmodel>
- <model>dac</model>
- <doi>0</doi>
- <baselabel type='kvm'>+487:+486</baselabel>
- <baselabel type='qemu'>+487:+486</baselabel>
- </secmodel>
- </host>
- <guest>
- <os_type>hvm</os_type>
- <arch name='i686'>
- <wordsize>32</wordsize>
- <emulator>/usr/bin/qemu-system-i386</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- <domain type='qemu'/>
- <domain type='kvm'>
- <emulator>/usr/bin/qemu-kvm</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- </domain>
- </arch>
- <features>
- <cpuselection/>
- <deviceboot/>
- <disksnapshot default='on' toggle='no'/>
- <acpi default='on' toggle='yes'/>
- <apic default='on' toggle='no'/>
- <pae/>
- <nonpae/>
- </features>
- </guest>
- <guest>
- <os_type>hvm</os_type>
- <arch name='x86_64'>
- <wordsize>64</wordsize>
- <emulator>/usr/bin/qemu-system-x86_64</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- <domain type='qemu'/>
- <domain type='kvm'>
- <emulator>/usr/bin/qemu-kvm</emulator>
- <machine maxCpus='255'>pc-i440fx-2.6</machine>
- <machine canonical='pc-i440fx-2.6' maxCpus='255'>pc</machine>
- <machine maxCpus='255'>pc-0.12</machine>
- </domain>
- </arch>
- <features>
- <cpuselection/>
- <deviceboot/>
- <disksnapshot default='on' toggle='no'/>
- <acpi default='on' toggle='yes'/>
- <apic default='on' toggle='no'/>
- </features>
- </guest>
- <guest>
- <os_type>xen</os_type>
- <arch name='x86_64'>
- <wordsize>64</wordsize>
- <emulator>/usr/bin/qemu-system-x86_64</emulator>
- <machine>xenpv</machine>
- <domain type='xen'/>
- </arch>
- </guest>
- </capabilities>
- '''
- self.mock_conn.getCapabilities.return_value = xml # pylint: disable=no-member
- caps = virt.capabilities()
- expected = {
- 'host': {
- 'uuid': '44454c4c-3400-105a-8033-b3c04f4b344a',
- 'cpu': {
- 'arch': 'x86_64',
- 'model': 'Nehalem',
- 'vendor': 'Intel',
- 'microcode': '25',
- 'sockets': 1,
- 'cores': 4,
- 'threads': 2,
- 'features': ['vme', 'ds', 'acpi'],
- 'pages': [{'size': '4 KiB'}, {'size': '2048 KiB'}]
- },
- 'power_management': ['suspend_mem', 'suspend_disk', 'suspend_hybrid'],
- 'migration': {
- 'live': True,
- 'transports': ['tcp', 'rdma']
- },
- 'topology': {
- 'cells': [
- {
- 'id': 0,
- 'memory': '12367120 KiB',
- 'pages': [
- {'size': '4 KiB', 'available': 3091780},
- {'size': '2048 KiB', 'available': 0}
- ],
- 'distances': {
- 0: 10,
- },
- 'cpus': [
- {'id': 0, 'socket_id': 0, 'core_id': 0, 'siblings': '0,4'},
- {'id': 1, 'socket_id': 0, 'core_id': 1, 'siblings': '1,5'},
- {'id': 2, 'socket_id': 0, 'core_id': 2, 'siblings': '2,6'},
- {'id': 3, 'socket_id': 0, 'core_id': 3, 'siblings': '3,7'},
- {'id': 4, 'socket_id': 0, 'core_id': 0, 'siblings': '0,4'},
- {'id': 5, 'socket_id': 0, 'core_id': 1, 'siblings': '1,5'},
- {'id': 6, 'socket_id': 0, 'core_id': 2, 'siblings': '2,6'},
- {'id': 7, 'socket_id': 0, 'core_id': 3, 'siblings': '3,7'}
- ]
- }
- ]
- },
- 'cache': {
- 'banks': [
- {'id': 0, 'level': 3, 'type': 'both', 'size': '8 MiB', 'cpus': '0-7'}
- ]
- },
- 'security': [
- {'model': 'apparmor', 'doi': '0', 'baselabels': []},
- {'model': 'dac', 'doi': '0', 'baselabels': [
- {'type': 'kvm', 'label': '+487:+486'},
- {'type': 'qemu', 'label': '+487:+486'}
- ]}
- ]
- },
- 'guests': [
- {
- 'os_type': 'hvm',
- 'arch': {
- 'name': 'i686',
- 'wordsize': 32,
- 'emulator': '/usr/bin/qemu-system-i386',
- 'machines': {
- 'pc-i440fx-2.6': {'maxcpus': 255, 'alternate_names': ['pc']},
- 'pc-0.12': {'maxcpus': 255, 'alternate_names': []}
- },
- 'domains': {
- 'qemu': {
- 'emulator': None,
- 'machines': {}
- },
- 'kvm': {
- 'emulator': '/usr/bin/qemu-kvm',
- 'machines': {
- 'pc-i440fx-2.6': {'maxcpus': 255, 'alternate_names': ['pc']},
- 'pc-0.12': {'maxcpus': 255, 'alternate_names': []}
- }
- }
- }
- },
- 'features': {
- 'cpuselection': {'default': True, 'toggle': False},
- 'deviceboot': {'default': True, 'toggle': False},
- 'disksnapshot': {'default': True, 'toggle': False},
- 'acpi': {'default': True, 'toggle': True},
- 'apic': {'default': True, 'toggle': False},
- 'pae': {'default': True, 'toggle': False},
- 'nonpae': {'default': True, 'toggle': False}
- }
- },
- {
- 'os_type': 'hvm',
- 'arch': {
- 'name': 'x86_64',
- 'wordsize': 64,
- 'emulator': '/usr/bin/qemu-system-x86_64',
- 'machines': {
- 'pc-i440fx-2.6': {'maxcpus': 255, 'alternate_names': ['pc']},
- 'pc-0.12': {'maxcpus': 255, 'alternate_names': []}
- },
- 'domains': {
- 'qemu': {
- 'emulator': None,
- 'machines': {}
- },
- 'kvm': {
- 'emulator': '/usr/bin/qemu-kvm',
- 'machines': {
- 'pc-i440fx-2.6': {'maxcpus': 255, 'alternate_names': ['pc']},
- 'pc-0.12': {'maxcpus': 255, 'alternate_names': []}
- }
- }
- }
- },
- 'features': {
- 'cpuselection': {'default': True, 'toggle': False},
- 'deviceboot': {'default': True, 'toggle': False},
- 'disksnapshot': {'default': True, 'toggle': False},
- 'acpi': {'default': True, 'toggle': True},
- 'apic': {'default': True, 'toggle': False}
- }
- },
- {
- 'os_type': 'xen',
- 'arch': {
- 'name': 'x86_64',
- 'wordsize': 64,
- 'emulator': '/usr/bin/qemu-system-x86_64',
- 'machines': {
- 'xenpv': {'alternate_names': []}
- },
- 'domains': {
- 'xen': {
- 'emulator': None,
- 'machines': {}
- }
- }
- }
- }
- ]
- }
- self.assertEqual(expected, caps)
- def test_network(self):
- '''
- Test virt._get_net_xml()
- '''
- xml_data = virt._gen_net_xml('network', 'main', 'bridge', 'openvswitch')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'network')
- self.assertEqual(root.find('bridge').attrib['name'], 'main')
- self.assertEqual(root.find('forward').attrib['mode'], 'bridge')
- self.assertEqual(root.find('virtualport').attrib['type'], 'openvswitch')
- def test_domain_capabilities(self):
- '''
- Test the virt.domain_capabilities parsing
- '''
- xml = '''
- <domainCapabilities>
- <path>/usr/bin/qemu-system-aarch64</path>
- <domain>kvm</domain>
- <machine>virt-2.12</machine>
- <arch>aarch64</arch>
- <vcpu max='255'/>
- <iothreads supported='yes'/>
- <os supported='yes'>
- <loader supported='yes'>
- <value>/usr/share/AAVMF/AAVMF_CODE.fd</value>
- <value>/usr/share/AAVMF/AAVMF32_CODE.fd</value>
- <value>/usr/share/OVMF/OVMF_CODE.fd</value>
- <enum name='type'>
- <value>rom</value>
- <value>pflash</value>
- </enum>
- <enum name='readonly'>
- <value>yes</value>
- <value>no</value>
- </enum>
- </loader>
- </os>
- <cpu>
- <mode name='host-passthrough' supported='yes'/>
- <mode name='host-model' supported='yes'>
- <model fallback='forbid'>sample-cpu</model>
- <vendor>ACME</vendor>
- <feature policy='require' name='vme'/>
- <feature policy='require' name='ss'/>
- </mode>
- <mode name='custom' supported='yes'>
- <model usable='unknown'>pxa262</model>
- <model usable='yes'>pxa270-a0</model>
- <model usable='no'>arm1136</model>
- </mode>
- </cpu>
- <devices>
- <disk supported='yes'>
- <enum name='diskDevice'>
- <value>disk</value>
- <value>cdrom</value>
- <value>floppy</value>
- <value>lun</value>
- </enum>
- <enum name='bus'>
- <value>fdc</value>
- <value>scsi</value>
- <value>virtio</value>
- <value>usb</value>
- <value>sata</value>
- </enum>
- </disk>
- <graphics supported='yes'>
- <enum name='type'>
- <value>sdl</value>
- <value>vnc</value>
- </enum>
- </graphics>
- <video supported='yes'>
- <enum name='modelType'>
- <value>vga</value>
- <value>virtio</value>
- </enum>
- </video>
- <hostdev supported='yes'>
- <enum name='mode'>
- <value>subsystem</value>
- </enum>
- <enum name='startupPolicy'>
- <value>default</value>
- <value>mandatory</value>
- <value>requisite</value>
- <value>optional</value>
- </enum>
- <enum name='subsysType'>
- <value>usb</value>
- <value>pci</value>
- <value>scsi</value>
- </enum>
- <enum name='capsType'/>
- <enum name='pciBackend'>
- <value>default</value>
- <value>kvm</value>
- <value>vfio</value>
- </enum>
- </hostdev>
- </devices>
- <features>
- <gic supported='yes'>
- <enum name='version'>
- <value>3</value>
- </enum>
- </gic>
- <vmcoreinfo supported='yes'/>
- </features>
- </domainCapabilities>
- '''
- self.mock_conn.getDomainCapabilities.return_value = xml # pylint: disable=no-member
- caps = virt.domain_capabilities()
- expected = {
- 'emulator': '/usr/bin/qemu-system-aarch64',
- 'domain': 'kvm',
- 'machine': 'virt-2.12',
- 'arch': 'aarch64',
- 'max_vcpus': 255,
- 'iothreads': True,
- 'os': {
- 'loader': {
- 'type': ['rom', 'pflash'],
- 'readonly': ['yes', 'no'],
- 'values': [
- '/usr/share/AAVMF/AAVMF_CODE.fd',
- '/usr/share/AAVMF/AAVMF32_CODE.fd',
- '/usr/share/OVMF/OVMF_CODE.fd'
- ]
- }
- },
- 'cpu': {
- 'host-passthrough': True,
- 'host-model': {
- 'model': {
- 'name': 'sample-cpu',
- 'fallback': 'forbid'
- },
- 'vendor': 'ACME',
- 'features': {
- 'vme': 'require',
- 'ss': 'require'
- }
- },
- 'custom': {
- 'models': {
- 'pxa262': 'unknown',
- 'pxa270-a0': 'yes',
- 'arm1136': 'no'
- }
- }
- },
- 'devices': {
- 'disk': {
- 'diskDevice': ['disk', 'cdrom', 'floppy', 'lun'],
- 'bus': ['fdc', 'scsi', 'virtio', 'usb', 'sata'],
- },
- 'graphics': {
- 'type': ['sdl', 'vnc']
- },
- 'video': {
- 'modelType': ['vga', 'virtio']
- },
- 'hostdev': {
- 'mode': ['subsystem'],
- 'startupPolicy': ['default', 'mandatory', 'requisite', 'optional'],
- 'subsysType': ['usb', 'pci', 'scsi'],
- 'capsType': [],
- 'pciBackend': ['default', 'kvm', 'vfio']
- }
- },
- 'features': {
- 'gic': {
- 'version': ['3']
- },
- 'vmcoreinfo': {}
- }
- }
- self.assertEqual(expected, caps)
- def test_network_tag(self):
- '''
- Test virt._get_net_xml() with VLAN tag
- '''
- xml_data = virt._gen_net_xml('network', 'main', 'bridge', 'openvswitch', 1001)
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'network')
- self.assertEqual(root.find('bridge').attrib['name'], 'main')
- self.assertEqual(root.find('forward').attrib['mode'], 'bridge')
- self.assertEqual(root.find('virtualport').attrib['type'], 'openvswitch')
- self.assertEqual(root.find('vlan/tag').attrib['id'], '1001')
- def test_list_networks(self):
- '''
- Test virt.list_networks()
- '''
- names = ['net1', 'default', 'net2']
- net_mocks = [MagicMock(), MagicMock(), MagicMock()]
- for i, value in enumerate(names):
- net_mocks[i].name.return_value = value
- self.mock_conn.listAllNetworks.return_value = net_mocks # pylint: disable=no-member
- actual = virt.list_networks()
- self.assertEqual(names, actual)
- def test_network_info(self):
- '''
- Test virt.network_info()
- '''
- self.mock_libvirt.VIR_IP_ADDR_TYPE_IPV4 = 0
- self.mock_libvirt.VIR_IP_ADDR_TYPE_IPV6 = 1
- net_mock = MagicMock()
- # pylint: disable=no-member
- net_mock.name.return_value = 'foo'
- net_mock.UUIDString.return_value = 'some-uuid'
- net_mock.bridgeName.return_value = 'br0'
- net_mock.autostart.return_value = True
- net_mock.isActive.return_value = False
- net_mock.isPersistent.return_value = True
- net_mock.DHCPLeases.return_value = [
- {
- 'iface': 'virbr0',
- 'expirytime': 1527757552,
- 'type': 0,
- 'mac': '52:54:00:01:71:bd',
- 'ipaddr': '192.168.122.45',
- 'prefix': 24,
- 'hostname': 'py3-test',
- 'clientid': '01:52:54:00:01:71:bd',
- 'iaid': None
- }
- ]
- self.mock_conn.listAllNetworks.return_value = [net_mock]
- # pylint: enable=no-member
- net = virt.network_info('foo')
- self.assertEqual({'foo': {
- 'uuid': 'some-uuid',
- 'bridge': 'br0',
- 'autostart': True,
- 'active': False,
- 'persistent': True,
- 'leases': [
- {
- 'iface': 'virbr0',
- 'expirytime': 1527757552,
- 'type': 'ipv4',
- 'mac': '52:54:00:01:71:bd',
- 'ipaddr': '192.168.122.45',
- 'prefix': 24,
- 'hostname': 'py3-test',
- 'clientid': '01:52:54:00:01:71:bd',
- 'iaid': None
- }
- ]}}, net)
- def test_network_info_all(self):
- '''
- Test virt.network_info()
- '''
- self.mock_libvirt.VIR_IP_ADDR_TYPE_IPV4 = 0
- self.mock_libvirt.VIR_IP_ADDR_TYPE_IPV6 = 1
- net_mocks = []
- # pylint: disable=no-member
- for i in range(2):
- net_mock = MagicMock()
- net_mock.name.return_value = 'net{0}'.format(i)
- net_mock.UUIDString.return_value = 'some-uuid'
- net_mock.bridgeName.return_value = 'br{0}'.format(i)
- net_mock.autostart.return_value = True
- net_mock.isActive.return_value = False
- net_mock.isPersistent.return_value = True
- net_mock.DHCPLeases.return_value = []
- net_mocks.append(net_mock)
- self.mock_conn.listAllNetworks.return_value = net_mocks
- # pylint: enable=no-member
- net = virt.network_info()
- self.assertEqual({
- 'net0':
- {
- 'uuid': 'some-uuid',
- 'bridge': 'br0',
- 'autostart': True,
- 'active': False,
- 'persistent': True,
- 'leases': []
- }, 'net1':
- {
- 'uuid': 'some-uuid',
- 'bridge': 'br1',
- 'autostart': True,
- 'active': False,
- 'persistent': True,
- 'leases': []
- }
- }, net)
- def test_network_info_notfound(self):
- '''
- Test virt.network_info() when the network can't be found
- '''
- # pylint: disable=no-member
- self.mock_conn.listAllNetworks.return_value = []
- # pylint: enable=no-member
- net = virt.network_info('foo')
- self.assertEqual({}, net)
- def test_pool(self):
- '''
- Test virt._gen_pool_xml()
- '''
- xml_data = virt._gen_pool_xml('pool', 'logical', '/dev/base')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'pool')
- self.assertEqual(root.attrib['type'], 'logical')
- self.assertEqual(root.find('target/path').text, '/dev/base')
- def test_pool_with_source(self):
- '''
- Test virt._gen_pool_xml() with a source device
- '''
- xml_data = virt._gen_pool_xml('pool', 'logical', '/dev/base', source_devices=[{'path': '/dev/sda'}])
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'pool')
- self.assertEqual(root.attrib['type'], 'logical')
- self.assertEqual(root.find('target/path').text, '/dev/base')
- self.assertEqual(root.find('source/device').attrib['path'], '/dev/sda')
- def test_pool_with_scsi(self):
- '''
- Test virt._gen_pool_xml() with a SCSI source
- '''
- xml_data = virt._gen_pool_xml('pool',
- 'scsi',
- '/dev/disk/by-path',
- source_devices=[{'path': '/dev/sda'}],
- source_adapter={
- 'type': 'scsi_host',
- 'parent_address': {
- 'unique_id': 5,
- 'address': {
- 'domain': '0x0000',
- 'bus': '0x00',
- 'slot': '0x1f',
- 'function': '0x2'
- }
- }
- },
- source_name='srcname')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'pool')
- self.assertEqual(root.attrib['type'], 'scsi')
- self.assertEqual(root.find('target/path').text, '/dev/disk/by-path')
- self.assertEqual(root.find('source/device'), None)
- self.assertEqual(root.find('source/name'), None)
- self.assertEqual(root.find('source/adapter').attrib['type'], 'scsi_host')
- self.assertEqual(root.find('source/adapter/parentaddr').attrib['unique_id'], '5')
- self.assertEqual(root.find('source/adapter/parentaddr/address').attrib['domain'], '0x0000')
- self.assertEqual(root.find('source/adapter/parentaddr/address').attrib['bus'], '0x00')
- self.assertEqual(root.find('source/adapter/parentaddr/address').attrib['slot'], '0x1f')
- self.assertEqual(root.find('source/adapter/parentaddr/address').attrib['function'], '0x2')
- def test_pool_with_rbd(self):
- '''
- Test virt._gen_pool_xml() with an RBD source
- '''
- xml_data = virt._gen_pool_xml('pool',
- 'rbd',
- source_devices=[{'path': '/dev/sda'}],
- source_hosts=['1.2.3.4', 'my.ceph.monitor:69'],
- source_auth={
- 'type': 'ceph',
- 'username': 'admin',
- 'secret': {
- 'type': 'uuid',
- 'value': 'someuuid'
- }
- },
- source_name='srcname',
- source_adapter={'type': 'scsi_host', 'name': 'host0'},
- source_dir='/some/dir',
- source_format='fmt')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'pool')
- self.assertEqual(root.attrib['type'], 'rbd')
- self.assertEqual(root.find('target'), None)
- self.assertEqual(root.find('source/device'), None)
- self.assertEqual(root.find('source/name').text, 'srcname')
- self.assertEqual(root.find('source/adapter'), None)
- self.assertEqual(root.find('source/dir'), None)
- self.assertEqual(root.find('source/format'), None)
- self.assertEqual(root.findall('source/host')[0].attrib['name'], '1.2.3.4')
- self.assertTrue('port' not in root.findall('source/host')[0].attrib)
- self.assertEqual(root.findall('source/host')[1].attrib['name'], 'my.ceph.monitor')
- self.assertEqual(root.findall('source/host')[1].attrib['port'], '69')
- self.assertEqual(root.find('source/auth').attrib['type'], 'ceph')
- self.assertEqual(root.find('source/auth').attrib['username'], 'admin')
- self.assertEqual(root.find('source/auth/secret').attrib['type'], 'uuid')
- self.assertEqual(root.find('source/auth/secret').attrib['uuid'], 'someuuid')
- def test_pool_with_netfs(self):
- '''
- Test virt._gen_pool_xml() with a netfs source
- '''
- xml_data = virt._gen_pool_xml('pool',
- 'netfs',
- target='/path/to/target',
- permissions={
- 'mode': '0770',
- 'owner': 1000,
- 'group': 100,
- 'label': 'seclabel'
- },
- source_devices=[{'path': '/dev/sda'}],
- source_hosts=['nfs.host'],
- source_name='srcname',
- source_adapter={'type': 'scsi_host', 'name': 'host0'},
- source_dir='/some/dir',
- source_format='nfs')
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find('name').text, 'pool')
- self.assertEqual(root.attrib['type'], 'netfs')
- self.assertEqual(root.find('target/path').text, '/path/to/target')
- self.assertEqual(root.find('target/permissions/mode').text, '0770')
- self.assertEqual(root.find('target/permissions/owner').text, '1000')
- self.assertEqual(root.find('target/permissions/group').text, '100')
- self.assertEqual(root.find('target/permissions/label').text, 'seclabel')
- self.assertEqual(root.find('source/device'), None)
- self.assertEqual(root.find('source/name'), None)
- self.assertEqual(root.find('source/adapter'), None)
- self.assertEqual(root.find('source/dir').attrib['path'], '/some/dir')
- self.assertEqual(root.find('source/format').attrib['type'], 'nfs')
- self.assertEqual(root.find('source/host').attrib['name'], 'nfs.host')
- self.assertEqual(root.find('source/auth'), None)
- def test_list_pools(self):
- '''
- Test virt.list_pools()
- '''
- names = ['pool1', 'default', 'pool2']
- pool_mocks = [MagicMock(), MagicMock(), MagicMock()]
- for i, value in enumerate(names):
- pool_mocks[i].name.return_value = value
- self.mock_conn.listAllStoragePools.return_value = pool_mocks # pylint: disable=no-member
- actual = virt.list_pools()
- self.assertEqual(names, actual)
- def test_pool_info(self):
- '''
- Test virt.pool_info()
- '''
- # pylint: disable=no-member
- pool_mock = MagicMock()
- pool_mock.name.return_value = 'foo'
- pool_mock.UUIDString.return_value = 'some-uuid'
- pool_mock.info.return_value = [0, 1234, 5678, 123]
- pool_mock.autostart.return_value = True
- pool_mock.isPersistent.return_value = True
- pool_mock.XMLDesc.return_value = '''<pool type='dir'>
- <name>default</name>
- <uuid>d92682d0-33cf-4e10-9837-a216c463e158</uuid>
- <capacity unit='bytes'>854374301696</capacity>
- <allocation unit='bytes'>596275986432</allocation>
- <available unit='bytes'>258098315264</available>
- <source>
- </source>
- <target>
- <path>/srv/vms</path>
- <permissions>
- <mode>0755</mode>
- <owner>0</owner>
- <group>0</group>
- </permissions>
- </target>
- </pool>'''
- self.mock_conn.listAllStoragePools.return_value = [pool_mock]
- # pylint: enable=no-member
- pool = virt.pool_info('foo')
- self.assertEqual({'foo': {
- 'uuid': 'some-uuid',
- 'state': 'inactive',
- 'capacity': 1234,
- 'allocation': 5678,
- 'free': 123,
- 'autostart': True,
- 'persistent': True,
- 'type': 'dir',
- 'target_path': '/srv/vms'}}, pool)
- def test_pool_info_notarget(self):
- '''
- Test virt.pool_info()
- '''
- # pylint: disable=no-member
- pool_mock = MagicMock()
- pool_mock.name.return_value = 'ceph'
- pool_mock.UUIDString.return_value = 'some-uuid'
- pool_mock.info.return_value = [0, 0, 0, 0]
- pool_mock.autostart.return_value = True
- pool_mock.isPersistent.return_value = True
- pool_mock.XMLDesc.return_value = '''<pool type='rbd'>
- <name>ceph</name>
- <uuid>some-uuid</uuid>
- <capacity unit='bytes'>0</capacity>
- <allocation unit='bytes'>0</allocation>
- <available unit='bytes'>0</available>
- <source>
- <host name='localhost' port='6789'/>
- <host name='localhost' port='6790'/>
- <name>rbd</name>
- <auth type='ceph' username='admin'>
- <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
- </auth>
- </source>
- </pool>'''
- self.mock_conn.listAllStoragePools.return_value = [pool_mock]
- # pylint: enable=no-member
- pool = virt.pool_info('ceph')
- self.assertEqual({'ceph': {
- 'uuid': 'some-uuid',
- 'state': 'inactive',
- 'capacity': 0,
- 'allocation': 0,
- 'free': 0,
- 'autostart': True,
- 'persistent': True,
- 'type': 'rbd',
- 'target_path': None}}, pool)
- def test_pool_info_notfound(self):
- '''
- Test virt.pool_info() when the pool can't be found
- '''
- # pylint: disable=no-member
- self.mock_conn.listAllStoragePools.return_value = []
- # pylint: enable=no-member
- pool = virt.pool_info('foo')
- self.assertEqual({}, pool)
- def test_pool_info_all(self):
- '''
- Test virt.pool_info()
- '''
- # pylint: disable=no-member
- pool_mocks = []
- for i in range(2):
- pool_mock = MagicMock()
- pool_mock.name.return_value = 'pool{0}'.format(i)
- pool_mock.UUIDString.return_value = 'some-uuid-{0}'.format(i)
- pool_mock.info.return_value = [0, 1234, 5678, 123]
- pool_mock.autostart.return_value = True
- pool_mock.isPersistent.return_value = True
- pool_mock.XMLDesc.return_value = '''<pool type='dir'>
- <name>default</name>
- <uuid>d92682d0-33cf-4e10-9837-a216c463e158</uuid>
- <capacity unit='bytes'>854374301696</capacity>
- <allocation unit='bytes'>596275986432</allocation>
- <available unit='bytes'>258098315264</available>
- <source>
- </source>
- <target>
- <path>/srv/vms</path>
- <permissions>
- <mode>0755</mode>
- <owner>0</owner>
- <group>0</group>
- </permissions>
- </target>
- </pool>'''
- pool_mocks.append(pool_mock)
- self.mock_conn.listAllStoragePools.return_value = pool_mocks
- # pylint: enable=no-member
- pool = virt.pool_info()
- self.assertEqual({
- 'pool0':
- {
- 'uuid': 'some-uuid-0',
- 'state': 'inactive',
- 'capacity': 1234,
- 'allocation': 5678,
- 'free': 123,
- 'autostart': True,
- 'persistent': True,
- 'type': 'dir',
- 'target_path': '/srv/vms'
- }, 'pool1': {
- 'uuid': 'some-uuid-1',
- 'state': 'inactive',
- 'capacity': 1234,
- 'allocation': 5678,
- 'free': 123,
- 'autostart': True,
- 'persistent': True,
- 'type': 'dir',
- 'target_path': '/srv/vms'
- }
- }, pool)
- def test_pool_list_volumes(self):
- '''
- Test virt.pool_list_volumes
- '''
- names = ['volume1', 'volume2']
- mock_pool = MagicMock()
- # pylint: disable=no-member
- mock_pool.listVolumes.return_value = names
- self.mock_conn.storagePoolLookupByName.return_value = mock_pool
- # pylint: enable=no-member
- self.assertEqual(names, virt.pool_list_volumes('default'))
|