Commit a8eeb651 authored by Jérome Perrin's avatar Jérome Perrin

cli/prune: fix a case where parts where not detected as used from a recursive instance

To consider if a shared part is used, we consider all files named `slapos.cfg`
in the instance and try to parse them as a slapos config file.
The problem was that as soon as a file can not be parsed as a slapos config
file, we did not continue to evaluate other `slapos.cfg` files. It was a
`return` where it should have been a `continue`.

This was especially incorrect, because when we have recursive slapos, we
usually have a working copy of slapos repository, which contain
`stack/slapos.cfg`, which is not a valid slapos config file.

As a result, when a top level shared part was used in a software installed
in the recursive slapos from a theia or slaprunner instance, this shared
part was not detected as used and could have been deleted.

The fix consist in checking all `slapos.cfg` files. This will make slapos
node prune command probably much slower, because it will really iterate on
all files now. Anyway this was fast because it was wrong.
parent 102f0ff3
...@@ -151,7 +151,7 @@ def getUsageSignaturesFromSubInstance(logger, instance_root): ...@@ -151,7 +151,7 @@ def getUsageSignaturesFromSubInstance(logger, instance_root):
for slapos_cfg in getInstanceSlaposCfgList(logger, instance_root): for slapos_cfg in getInstanceSlaposCfgList(logger, instance_root):
cfg = readSlaposCfg(logger, slapos_cfg) cfg = readSlaposCfg(logger, slapos_cfg)
if not cfg: if not cfg:
return {} continue
shared_root = None shared_root = None
if cfg['shared_part_list']: if cfg['shared_part_list']:
shared_root = cfg['shared_part_list'][-1] shared_root = cfg['shared_part_list'][-1]
......
...@@ -255,3 +255,37 @@ shared_part_list = NOT EXIST SHARED PART ...@@ -255,3 +255,37 @@ shared_part_list = NOT EXIST SHARED PART
'NOT EXIST SHARED PART', 'NOT EXIST SHARED PART',
instance_slapos_cfg), instance_slapos_cfg),
self.logger.debug.mock_calls) self.logger.debug.mock_calls)
def test_recursive_instance_broken_slapos_cfg_does_not_cause_instance_to_be_ignored(self):
used_in_software_from_instance = self._createSharedPart('used_in_software_from_instance')
instance = os.path.join(self.instance_root, 'slappart0')
instance_software = os.path.join(instance, 'software')
os.makedirs(instance_software)
software_in_instance = self._createFakeSoftware(
'soft_in_instance',
using=used_in_software_from_instance,
software_root=instance_software
)
# a broken slapos.cfg
folder_containing_wrong_slapos_cfg = os.path.join(instance, 'aaa')
os.makedirs(folder_containing_wrong_slapos_cfg)
wrong_slapos_cfg = os.path.join(folder_containing_wrong_slapos_cfg, 'slapos.cfg')
with open(wrong_slapos_cfg, 'w') as f:
f.write("broken")
# a "real" slapos.cfg
instance_etc = os.path.join(instance, 'etc')
os.makedirs(instance_etc)
instance_slapos_cfg = os.path.join(instance_etc, 'slapos.cfg')
with open(instance_slapos_cfg, 'w') as f:
f.write('''
[slapos]
software_root = {instance_software}
instance_root = anything
shared_part_list = anything
'''.format(**locals()))
do_prune(self.logger, self.config, False)
self.assertTrue(os.path.exists(used_in_software_from_instance))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment