[PATCHv4 0/4] Add volume reference count

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Available volumes will be tracked by volume reference count. Add this field to storage volume, so that storage volume/pool action validation can rely on it. Royce Lv (4): Add volume ref_cnt: update api.md Add volume ref_cnt: Update controller and json schema Add volume ref_cnt: Add model and mockmodel implementation Add volume ref_cnt: Update test docs/API.md | 3 +++ src/kimchi/API.json | 25 +++++++++++++++++++++++++ src/kimchi/control/storagevolumes.py | 1 + src/kimchi/i18n.py | 4 ++++ src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ tests/test_model.py | 4 ++++ tests/test_rest.py | 2 ++ 8 files changed, 73 insertions(+) -- 1.8.1.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Update doc to support storage volume reference count. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- docs/API.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/API.md b/docs/API.md index e97eace..e3f9ae1 100644 --- a/docs/API.md +++ b/docs/API.md @@ -395,6 +395,9 @@ A interface represents available network interface on VM. * 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. + * ref_cnt: Number of vms which used this volume, + 0 for volumes which are available for attachment. + >1 indicate number of vms used this volume. * **DELETE**: Remove the Storage Volume * **POST**: *See Storage Volume Actions* -- 1.8.1.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Add ref_cnt to controller to report reference count information. Update json schema validation. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/API.json | 25 +++++++++++++++++++++++++ src/kimchi/control/storagevolumes.py | 1 + src/kimchi/i18n.py | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/src/kimchi/API.json b/src/kimchi/API.json index f595bbf..b519fec 100644 --- a/src/kimchi/API.json +++ b/src/kimchi/API.json @@ -143,6 +143,31 @@ } } }, + "storagevolumes_create": { + "type": "object", + "error": "KCHVOL0015E", + "properties": { + "name": { + "description": "The name of the Storage Volume", + "type": "string", + "minLength": 1, + "required": true, + "error": "KCHVOL0012E" + }, + "allocation": { + "description": "The size(MiB) of allocation when create the storage volume", + "type": "number", + "minimum": 1, + "error": "KCHVOL0013E" + }, + "format": { + "description": "The format of the volume", + "type": "string", + "pattern": "^qcow2|raw$", + "error": "KCHVOL0014E" + } + } + }, "vms_create": { "type": "object", "error": "KCHVM0016E", diff --git a/src/kimchi/control/storagevolumes.py b/src/kimchi/control/storagevolumes.py index 718c97a..c4d6c41 100644 --- a/src/kimchi/control/storagevolumes.py +++ b/src/kimchi/control/storagevolumes.py @@ -49,6 +49,7 @@ class StorageVolume(Resource): 'capacity': self.info['capacity'], 'allocation': self.info['allocation'], 'path': self.info['path'], + 'ref_cnt': self.info['ref_cnt'], 'format': self.info['format']} for key in ('os_version', 'os_distro', 'bootable'): diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index e22bb4b..32126e5 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -149,6 +149,10 @@ messages = { "KCHVOL0009E": _("Unable to wipe storage volumes %(name)s. Details: %(err)s"), "KCHVOL0010E": _("Unable to delete storage volume %(name)s. Details: %(err)s"), "KCHVOL0011E": _("Unable to resize storage volume %(name)s. Details: %(err)s"), + "KCHVOL0012E": _("Storage volume name must be a string"), + "KCHVOL0013E": _("Storage volume allocation must be an integer number"), + "KCHVOL0014E": _("Storage volume format not supported"), + "KCHVOL0015E": _("Storage volume requires a volume name"), "KCHIFACE0001E": _("Interface %(name)s does not exist"), -- 1.8.1.2

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Set ref_cnt to 0 when new volume created, if the ref_cnt cannot be found, which means it is created outside of kimchi scope, report it when lookup storage volume, search info about storage volumes used by vms and count the ref_cnt. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py index 50b5f0e..b250eea 100644 --- a/src/kimchi/mockmodel.py +++ b/src/kimchi/mockmodel.py @@ -420,6 +420,7 @@ class MockModel(object): name = params['name'] volume = MockStorageVolume(pool, name, params) volume.info['type'] = params['type'] + volume.info['ref_cnt'] = params.get('ref_cnt', 0) volume.info['format'] = params['format'] volume.info['path'] = os.path.join( pool.info['path'], name) @@ -881,6 +882,7 @@ class MockVMTemplate(VMTemplate): disk_paths = [] for vol_info in volumes: vol_info['capacity'] = vol_info['capacity'] << 10 + vol_info['ref_cnt'] = 1 self.model.storagevolumes_create(pool.name, vol_info) disk_paths.append({'pool': pool.name, 'volume': vol_info['name']}) return disk_paths @@ -999,6 +1001,7 @@ class MockStorageVolume(object): 'capacity': capacity << 20, 'allocation': params.get('allocation', '512'), 'path': params.get('path'), + 'ref_cnt': params.get('ref_cnt'), 'format': fmt} if fmt == 'iso': self.info['allocation'] = self.info['capacity'] diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py index 8defdb7..3fd7335 100644 --- a/src/kimchi/model/storagevolumes.py +++ b/src/kimchi/model/storagevolumes.py @@ -26,6 +26,8 @@ from kimchi.exception import InvalidOperation, IsoFormatError from kimchi.exception import MissingParameter, NotFoundError, OperationFailed from kimchi.isoinfo import IsoImage from kimchi.model.storagepools import StoragePoolModel +from kimchi.model.vms import VMsModel +from kimchi.model.vmstorages import VMStoragesModel, VMStorageModel VOLUME_TYPE_MAP = {0: 'file', @@ -37,6 +39,7 @@ VOLUME_TYPE_MAP = {0: 'file', class StorageVolumesModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] + self.objstore = kargs['objstore'] def create(self, pool, params): vol_xml = """ @@ -55,6 +58,7 @@ class StorageVolumesModel(object): params.setdefault('format', 'qcow2') name = params['name'] + vol_id = '%s:%s' % (pool, name) try: pool = StoragePoolModel.get_storagepool(pool, self.conn) xml = vol_xml % params @@ -68,6 +72,10 @@ class StorageVolumesModel(object): raise OperationFailed("KCHVOL0007E", {'name': name, 'pool': pool, 'err': e.get_error_message()}) + + with self.objstore as session: + session.store('storagevolume', vol_id, {'ref_cnt': 0}) + return name def get_list(self, pool_name): @@ -86,6 +94,7 @@ class StorageVolumesModel(object): class StorageVolumeModel(object): def __init__(self, **kargs): self.conn = kargs['conn'] + self.objstore = kargs['objstore'] def _get_storagevolume(self, pool, name): pool = StoragePoolModel.get_storagepool(pool, self.conn) @@ -100,16 +109,38 @@ class StorageVolumeModel(object): else: raise + def _get_ref_cnt(self, pool, name, path): + vol_id = '%s:%s' % (pool, name) + with self.objstore as session: + try: + ref_cnt = session.get('storagevolume', vol_id)['ref_cnt'] + except NotFoundError: + # Fix storage volume created outside kimchi scope + ref_cnt = 0 + args = {'conn': self.conn, 'objstore': self.objstore} + # try to find this volume in exsisted vm + vms = VMsModel(**args).get_list() + for vm in vms: + storages = VMStoragesModel(**args).get_list(vm) + for disk in storages: + if path == VMStorageModel(**args).lookup(vm, disk)['path']: + ref_cnt = ref_cnt + 1 + session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt}) + + return ref_cnt + def lookup(self, pool, name): vol = self._get_storagevolume(pool, name) path = vol.path() info = vol.info() xml = vol.XMLDesc(0) fmt = xmlutils.xpath_get_text(xml, "/volume/target/format/@type")[0] + ref_cnt = self._get_ref_cnt(pool, name, path) res = dict(type=VOLUME_TYPE_MAP[info[0]], capacity=info[1], allocation=info[2], path=path, + ref_cnt=ref_cnt, format=fmt) if fmt == 'iso': if os.path.islink(path): -- 1.8.1.2

On 02/27/2014 06:49 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Set ref_cnt to 0 when new volume created, if the ref_cnt cannot be found, which means it is created outside of kimchi scope, report it when lookup storage volume, search info about storage volumes used by vms and count the ref_cnt.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
+ def _get_ref_cnt(self, pool, name, path):
i don't know the hole workflow of this function, but will be nice to check if the parameters are valid. If the function that calls this one already to that, consider my review: Reviewed-By: Ramon Medeiros <ramonn@br.ibm.com>
+ vol_id = '%s:%s' % (pool, name) + with self.objstore as session: + try: + ref_cnt = session.get('storagevolume', vol_id)['ref_cnt'] + except NotFoundError: + # Fix storage volume created outside kimchi scope + ref_cnt = 0 + args = {'conn': self.conn, 'objstore': self.objstore} + # try to find this volume in exsisted vm + vms = VMsModel(**args).get_list() + for vm in vms: + storages = VMStoragesModel(**args).get_list(vm) + for disk in storages: + if path == VMStorageModel(**args).lookup(vm, disk)['path']: + ref_cnt = ref_cnt + 1 + session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt}) + + return ref_cnt + def lookup(self, pool, name): vol = self._get_storagevolume(pool, name) path = vol.path() info = vol.info() xml = vol.XMLDesc(0) fmt = xmlutils.xpath_get_text(xml, "/volume/target/format/@type")[0] + ref_cnt = self._get_ref_cnt(pool, name, path) res = dict(type=VOLUME_TYPE_MAP[info[0]], capacity=info[1], allocation=info[2], path=path, + ref_cnt=ref_cnt, format=fmt) if fmt == 'iso': if os.path.islink(path):
-- Ramon Nunes Medeiros Software Engineer - Linux Technology Center Brazil IBM Systems & Technology Group Phone : +55 19 2132 7878 ramonn@br.ibm.com

On 03/03/2014 02:57 PM, Ramon Medeiros wrote:
On 02/27/2014 06:49 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Set ref_cnt to 0 when new volume created, if the ref_cnt cannot be found, which means it is created outside of kimchi scope, report it when lookup storage volume, search info about storage volumes used by vms and count the ref_cnt.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
+ def _get_ref_cnt(self, pool, name, path):
i don't know the hole workflow of this function, but will be nice to check if the parameters are valid.
It is already done on control through jsonschema. Because that on previous patch Royce updates the API.json
If the function that calls this one already to that, consider my review:
Reviewed-By: Ramon Medeiros <ramonn@br.ibm.com>
+ vol_id = '%s:%s' % (pool, name) + with self.objstore as session: + try: + ref_cnt = session.get('storagevolume', vol_id)['ref_cnt'] + except NotFoundError: + # Fix storage volume created outside kimchi scope + ref_cnt = 0 + args = {'conn': self.conn, 'objstore': self.objstore} + # try to find this volume in exsisted vm + vms = VMsModel(**args).get_list() + for vm in vms: + storages = VMStoragesModel(**args).get_list(vm) + for disk in storages: + if path == VMStorageModel(**args).lookup(vm, disk)['path']: + ref_cnt = ref_cnt + 1 + session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt}) + + return ref_cnt + def lookup(self, pool, name): vol = self._get_storagevolume(pool, name) path = vol.path() info = vol.info() xml = vol.XMLDesc(0) fmt = xmlutils.xpath_get_text(xml, "/volume/target/format/@type")[0] + ref_cnt = self._get_ref_cnt(pool, name, path) res = dict(type=VOLUME_TYPE_MAP[info[0]], capacity=info[1], allocation=info[2], path=path, + ref_cnt=ref_cnt, format=fmt) if fmt == 'iso': if os.path.islink(path):

On 02/27/2014 06:49 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Set ref_cnt to 0 when new volume created, if the ref_cnt cannot be found, which means it is created outside of kimchi scope, report it when lookup storage volume, search info about storage volumes used by vms and count the ref_cnt.
Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
+ def _get_ref_cnt(self, pool, name, path):
i don't know the hole workflow of this function, but will be nice to check if the parameters are valid.
If the function that calls this one already to that, consider my review:
Reviewed-By: Ramon Medeiros <ramonn@br.ibm.com> For pool and name we validate earlier, for path I took a look at storagevolume libvirt implementation,
On 2014年03月04日 01:57, Ramon Medeiros wrote: the path will not be none, so there won't be corner case violate this function. But thorough consideration of param passing is always helpful, thanks a lot for your careful review!
+ vol_id = '%s:%s' % (pool, name) + with self.objstore as session: + try: + ref_cnt = session.get('storagevolume', vol_id)['ref_cnt'] + except NotFoundError: + # Fix storage volume created outside kimchi scope + ref_cnt = 0 + args = {'conn': self.conn, 'objstore': self.objstore} + # try to find this volume in exsisted vm + vms = VMsModel(**args).get_list() + for vm in vms: + storages = VMStoragesModel(**args).get_list(vm) + for disk in storages: + if path == VMStorageModel(**args).lookup(vm, disk)['path']: + ref_cnt = ref_cnt + 1 + session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt}) + + return ref_cnt + def lookup(self, pool, name): vol = self._get_storagevolume(pool, name) path = vol.path() info = vol.info() xml = vol.XMLDesc(0) fmt = xmlutils.xpath_get_text(xml, "/volume/target/format/@type")[0] + ref_cnt = self._get_ref_cnt(pool, name, path) res = dict(type=VOLUME_TYPE_MAP[info[0]], capacity=info[1], allocation=info[2], path=path, + ref_cnt=ref_cnt, format=fmt) if fmt == 'iso': if os.path.islink(path):

From: Royce Lv <lvroyce@linux.vnet.ibm.com> Add mockmodel test and model test to validate: 1. ref_cnt of storage volume forked internal vm creation is 1. 2. ref_cnt of storage volume created from REST API is 0. Signed-off-by: Royce Lv <lvroyce@linux.vnet.ibm.com> --- tests/test_model.py | 4 ++++ tests/test_rest.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tests/test_model.py b/tests/test_model.py index 2b34619..0115cdd 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -353,6 +353,7 @@ class ModelTests(unittest.TestCase): inst.storagevolume_wipe(pool, vol) volinfo = inst.storagevolume_lookup(pool, vol) self.assertEquals(0, volinfo['allocation']) + self.assertEquals(0, volinfo['ref_cnt']) volinfo = inst.storagevolume_lookup(pool, vol) # Define the size = capacity + 16M @@ -402,6 +403,9 @@ class ModelTests(unittest.TestCase): vm_info = inst.vm_lookup(params['name']) disk_path = '/tmp/kimchi-images/%s-0.img' % vm_info['uuid'] self.assertTrue(os.access(disk_path, os.F_OK)) + vol = '%s-0.img' % vm_info['uuid'] + volinfo = inst.storagevolume_lookup(pool, vol) + self.assertEquals(1, volinfo['ref_cnt']) # reset template to default storage pool # so we can remove the storage pool created 'test-pool' diff --git a/tests/test_rest.py b/tests/test_rest.py index ced9a33..a605e08 100644 --- a/tests/test_rest.py +++ b/tests/test_rest.py @@ -243,6 +243,7 @@ class RestTests(unittest.TestCase): resp = self.request(vol_uri) vol = json.loads(resp.read()) self.assertEquals(1 << 30, vol['capacity']) + self.assertEquals(1, vol['ref_cnt']) # Start the VM resp = self.request('/vms/test-vm/start', '{}', 'POST') @@ -843,6 +844,7 @@ class RestTests(unittest.TestCase): storagevolume = json.loads(resp.read()) self.assertEquals('volume-1', storagevolume['name']) self.assertEquals('raw', storagevolume['format']) + self.assertEquals(0, storagevolume['ref_cnt']) self.assertEquals('/var/lib/libvirt/images/volume-1', storagevolume['path']) -- 1.8.1.2

The tests are failing with this patch set: ====================================================================== ERROR: test_template_storage_customise (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_model.py", line 407, in test_template_storage_customise volinfo = inst.storagevolume_lookup(pool, vol) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 139, in lookup ref_cnt = self._get_ref_cnt(pool, name, path) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 127, in _get_ref_cnt if path == VMStorageModel(**args).lookup(vm, disk)['path']: File "/home/alinefm/kimchi/src/kimchi/model/vmstorages.py", line 166, in lookup source = disk.source File "lxml.objectify.pyx", line 226, in lxml.objectify.ObjectifiedElement.__getattr__ (src/lxml/lxml.objectify.c:2894) File "lxml.objectify.pyx", line 485, in lxml.objectify._lookupChildOrRaise (src/lxml/lxml.objectify.c:5428) AttributeError: no such child: source ---------------------------------------------------------------------- Ran 157 tests in 136.021s FAILED (errors=1) make[3]: *** [check-local] Error 1 make[3]: Leaving directory `/home/alinefm/kimchi/tests' make[2]: *** [check-am] Error 2 make[2]: Leaving directory `/home/alinefm/kimchi/tests' make[1]: *** [check] Error 2 make[1]: Leaving directory `/home/alinefm/kimchi/tests' make: *** [check-recursive] Error 1 On 02/27/2014 06:48 AM, lvroyce@linux.vnet.ibm.com wrote:
From: Royce Lv <lvroyce@linux.vnet.ibm.com>
Available volumes will be tracked by volume reference count. Add this field to storage volume, so that storage volume/pool action validation can rely on it.
Royce Lv (4): Add volume ref_cnt: update api.md Add volume ref_cnt: Update controller and json schema Add volume ref_cnt: Add model and mockmodel implementation Add volume ref_cnt: Update test
docs/API.md | 3 +++ src/kimchi/API.json | 25 +++++++++++++++++++++++++ src/kimchi/control/storagevolumes.py | 1 + src/kimchi/i18n.py | 4 ++++ src/kimchi/mockmodel.py | 3 +++ src/kimchi/model/storagevolumes.py | 31 +++++++++++++++++++++++++++++++ tests/test_model.py | 4 ++++ tests/test_rest.py | 2 ++ 8 files changed, 73 insertions(+)

Please, run "sudo make check" before submitting patches. Am 03-03-2014 15:22, schrieb Aline Manera:
The tests are failing with this patch set:
====================================================================== ERROR: test_template_storage_customise (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_model.py", line 407, in test_template_storage_customise volinfo = inst.storagevolume_lookup(pool, vol) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 139, in lookup ref_cnt = self._get_ref_cnt(pool, name, path) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 127, in _get_ref_cnt if path == VMStorageModel(**args).lookup(vm, disk)['path']: File "/home/alinefm/kimchi/src/kimchi/model/vmstorages.py", line 166, in lookup source = disk.source File "lxml.objectify.pyx", line 226, in lxml.objectify.ObjectifiedElement.__getattr__ (src/lxml/lxml.objectify.c:2894) File "lxml.objectify.pyx", line 485, in lxml.objectify._lookupChildOrRaise (src/lxml/lxml.objectify.c:5428) AttributeError: no such child: source
---------------------------------------------------------------------- Ran 157 tests in 136.021s
FAILED (errors=1) make[3]: *** [check-local] Error 1 make[3]: Leaving directory `/home/alinefm/kimchi/tests' make[2]: *** [check-am] Error 2 make[2]: Leaving directory `/home/alinefm/kimchi/tests' make[1]: *** [check] Error 2 make[1]: Leaving directory `/home/alinefm/kimchi/tests' make: *** [check-recursive] Error 1

Cristian, I have run make check every time before submitting patch. And this bug is fixed by [Kimchi-devel][PATCHv3 1/5] Fix vm disk path when it does not have source element. For cdrom it sometimes doesn't have source. Because Aline commented why this is needed last time so I splitted these two because they are not related. And as you can see, this bug is not introduced by my patch and is env dependent (can not be reproduced on every env). But nevertherless, I will repost this patchset with the bug fix patch. On 2014年03月04日 02:28, Crístian Viana wrote:
Please, run "sudo make check" before submitting patches.
Am 03-03-2014 15:22, schrieb Aline Manera:
The tests are failing with this patch set:
====================================================================== ERROR: test_template_storage_customise (test_model.ModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/alinefm/kimchi/tests/test_model.py", line 407, in test_template_storage_customise volinfo = inst.storagevolume_lookup(pool, vol) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 139, in lookup ref_cnt = self._get_ref_cnt(pool, name, path) File "/home/alinefm/kimchi/src/kimchi/model/storagevolumes.py", line 127, in _get_ref_cnt if path == VMStorageModel(**args).lookup(vm, disk)['path']: File "/home/alinefm/kimchi/src/kimchi/model/vmstorages.py", line 166, in lookup source = disk.source File "lxml.objectify.pyx", line 226, in lxml.objectify.ObjectifiedElement.__getattr__ (src/lxml/lxml.objectify.c:2894) File "lxml.objectify.pyx", line 485, in lxml.objectify._lookupChildOrRaise (src/lxml/lxml.objectify.c:5428) AttributeError: no such child: source
---------------------------------------------------------------------- Ran 157 tests in 136.021s
FAILED (errors=1) make[3]: *** [check-local] Error 1 make[3]: Leaving directory `/home/alinefm/kimchi/tests' make[2]: *** [check-am] Error 2 make[2]: Leaving directory `/home/alinefm/kimchi/tests' make[1]: *** [check] Error 2 make[1]: Leaving directory `/home/alinefm/kimchi/tests' make: *** [check-recursive] Error 1
participants (5)
-
Aline Manera
-
Crístian Viana
-
lvroyce@linux.vnet.ibm.com
-
Ramon Medeiros
-
Royce Lv