1*1596Szelenkov@nginx.comimport pytest 21490St.nateldemoura@f5.com 31490St.nateldemoura@f5.comfrom unit.applications.lang.python import TestApplicationPython 41490St.nateldemoura@f5.comfrom unit.feature.isolation import TestFeatureIsolation 51490St.nateldemoura@f5.com 61490St.nateldemoura@f5.com 71490St.nateldemoura@f5.comclass TestPythonIsolation(TestApplicationPython): 81490St.nateldemoura@f5.com prerequisites = {'modules': {'python': 'any'}, 'features': ['isolation']} 91490St.nateldemoura@f5.com 101490St.nateldemoura@f5.com isolation = TestFeatureIsolation() 111490St.nateldemoura@f5.com 121490St.nateldemoura@f5.com @classmethod 13*1596Szelenkov@nginx.com def setup_class(cls, complete_check=True): 14*1596Szelenkov@nginx.com unit = super().setup_class(complete_check=False) 151490St.nateldemoura@f5.com 16*1596Szelenkov@nginx.com TestFeatureIsolation().check(cls.available, unit.temp_dir) 171490St.nateldemoura@f5.com 181490St.nateldemoura@f5.com return unit if not complete_check else unit.complete() 191490St.nateldemoura@f5.com 20*1596Szelenkov@nginx.com def test_python_isolation_rootfs(self, is_su): 211490St.nateldemoura@f5.com isolation_features = self.available['features']['isolation'].keys() 221490St.nateldemoura@f5.com 231490St.nateldemoura@f5.com if 'mnt' not in isolation_features: 24*1596Szelenkov@nginx.com pytest.skip('requires mnt ns') 251490St.nateldemoura@f5.com 26*1596Szelenkov@nginx.com if not is_su: 271490St.nateldemoura@f5.com if 'user' not in isolation_features: 28*1596Szelenkov@nginx.com pytest.skip('requires unprivileged userns or root') 291490St.nateldemoura@f5.com 301490St.nateldemoura@f5.com if not 'unprivileged_userns_clone' in isolation_features: 31*1596Szelenkov@nginx.com pytest.skip('requires unprivileged userns or root') 321490St.nateldemoura@f5.com 331490St.nateldemoura@f5.com isolation = { 34*1596Szelenkov@nginx.com 'namespaces': {'credential': not is_su, 'mount': True}, 35*1596Szelenkov@nginx.com 'rootfs': self.temp_dir, 361490St.nateldemoura@f5.com } 371490St.nateldemoura@f5.com 381490St.nateldemoura@f5.com self.load('empty', isolation=isolation) 391490St.nateldemoura@f5.com 40*1596Szelenkov@nginx.com assert self.get()['status'] == 200, 'python rootfs' 411490St.nateldemoura@f5.com 421490St.nateldemoura@f5.com self.load('ns_inspect', isolation=isolation) 431490St.nateldemoura@f5.com 44*1596Szelenkov@nginx.com assert ( 45*1596Szelenkov@nginx.com self.getjson(url='/?path=' + self.temp_dir)['body']['FileExists'] 46*1596Szelenkov@nginx.com == False 47*1596Szelenkov@nginx.com ), 'temp_dir does not exists in rootfs' 481490St.nateldemoura@f5.com 49*1596Szelenkov@nginx.com assert ( 50*1596Szelenkov@nginx.com self.getjson(url='/?path=/proc/self')['body']['FileExists'] 51*1596Szelenkov@nginx.com == False 52*1596Szelenkov@nginx.com ), 'no /proc/self' 531490St.nateldemoura@f5.com 54*1596Szelenkov@nginx.com assert ( 55*1596Szelenkov@nginx.com self.getjson(url='/?path=/dev/pts')['body']['FileExists'] == False 56*1596Szelenkov@nginx.com ), 'no /dev/pts' 57*1596Szelenkov@nginx.com 58*1596Szelenkov@nginx.com assert ( 59*1596Szelenkov@nginx.com self.getjson(url='/?path=/sys/kernel')['body']['FileExists'] 60*1596Szelenkov@nginx.com == False 61*1596Szelenkov@nginx.com ), 'no /sys/kernel' 621490St.nateldemoura@f5.com 631490St.nateldemoura@f5.com ret = self.getjson(url='/?path=/app/python/ns_inspect') 641490St.nateldemoura@f5.com 65*1596Szelenkov@nginx.com assert ( 66*1596Szelenkov@nginx.com ret['body']['FileExists'] == True 67*1596Szelenkov@nginx.com ), 'application exists in rootfs' 68