11654Szelenkov@nginx.com 21596Szelenkov@nginx.comimport pytest 31490St.nateldemoura@f5.comfrom unit.applications.lang.python import TestApplicationPython 41730Szelenkov@nginx.comfrom unit.option import option 51773Szelenkov@nginx.comfrom unit.utils import findmnt 61773Szelenkov@nginx.comfrom unit.utils import waitformount 71773Szelenkov@nginx.comfrom unit.utils import waitforunmount 81490St.nateldemoura@f5.com 91490St.nateldemoura@f5.com 101490St.nateldemoura@f5.comclass TestPythonIsolation(TestApplicationPython): 111490St.nateldemoura@f5.com prerequisites = {'modules': {'python': 'any'}, 'features': ['isolation']} 121490St.nateldemoura@f5.com 131654Szelenkov@nginx.com def test_python_isolation_rootfs(self, is_su, temp_dir): 141654Szelenkov@nginx.com isolation_features = option.available['features']['isolation'].keys() 151490St.nateldemoura@f5.com 161596Szelenkov@nginx.com if not is_su: 171490St.nateldemoura@f5.com if not 'unprivileged_userns_clone' in isolation_features: 181596Szelenkov@nginx.com pytest.skip('requires unprivileged userns or root') 191490St.nateldemoura@f5.com 201673St.nateldemoura@f5.com if 'user' not in isolation_features: 211673St.nateldemoura@f5.com pytest.skip('user namespace is not supported') 221673St.nateldemoura@f5.com 231673St.nateldemoura@f5.com if 'mnt' not in isolation_features: 241673St.nateldemoura@f5.com pytest.skip('mnt namespace is not supported') 251673St.nateldemoura@f5.com 261673St.nateldemoura@f5.com if 'pid' not in isolation_features: 271673St.nateldemoura@f5.com pytest.skip('pid namespace is not supported') 281490St.nateldemoura@f5.com 291673St.nateldemoura@f5.com isolation = {'rootfs': temp_dir} 301490St.nateldemoura@f5.com 311673St.nateldemoura@f5.com if not is_su: 321673St.nateldemoura@f5.com isolation['namespaces'] = { 331673St.nateldemoura@f5.com 'mount': True, 341673St.nateldemoura@f5.com 'credential': True, 351673St.nateldemoura@f5.com 'pid': True 361673St.nateldemoura@f5.com } 371490St.nateldemoura@f5.com 381490St.nateldemoura@f5.com self.load('ns_inspect', isolation=isolation) 391490St.nateldemoura@f5.com 401596Szelenkov@nginx.com assert ( 411654Szelenkov@nginx.com self.getjson(url='/?path=' + temp_dir)['body']['FileExists'] 421596Szelenkov@nginx.com == False 431596Szelenkov@nginx.com ), 'temp_dir does not exists in rootfs' 441490St.nateldemoura@f5.com 451596Szelenkov@nginx.com assert ( 461596Szelenkov@nginx.com self.getjson(url='/?path=/proc/self')['body']['FileExists'] 471673St.nateldemoura@f5.com == True 481596Szelenkov@nginx.com ), 'no /proc/self' 491490St.nateldemoura@f5.com 501596Szelenkov@nginx.com assert ( 511596Szelenkov@nginx.com self.getjson(url='/?path=/dev/pts')['body']['FileExists'] == False 521596Szelenkov@nginx.com ), 'no /dev/pts' 531596Szelenkov@nginx.com 541596Szelenkov@nginx.com assert ( 551596Szelenkov@nginx.com self.getjson(url='/?path=/sys/kernel')['body']['FileExists'] 561596Szelenkov@nginx.com == False 571596Szelenkov@nginx.com ), 'no /sys/kernel' 581490St.nateldemoura@f5.com 591490St.nateldemoura@f5.com ret = self.getjson(url='/?path=/app/python/ns_inspect') 601490St.nateldemoura@f5.com 611596Szelenkov@nginx.com assert ( 621596Szelenkov@nginx.com ret['body']['FileExists'] == True 631596Szelenkov@nginx.com ), 'application exists in rootfs' 641622St.nateldemoura@f5.com 651654Szelenkov@nginx.com def test_python_isolation_rootfs_no_language_deps(self, is_su, temp_dir): 661622St.nateldemoura@f5.com if not is_su: 671773Szelenkov@nginx.com pytest.skip('requires root') 681673St.nateldemoura@f5.com 691622St.nateldemoura@f5.com isolation = { 701654Szelenkov@nginx.com 'rootfs': temp_dir, 711622St.nateldemoura@f5.com 'automount': {'language_deps': False} 721622St.nateldemoura@f5.com } 731622St.nateldemoura@f5.com 741622St.nateldemoura@f5.com self.load('empty', isolation=isolation) 751622St.nateldemoura@f5.com 761773Szelenkov@nginx.com assert findmnt().find(temp_dir) == -1 771622St.nateldemoura@f5.com assert (self.get()['status'] != 200), 'disabled language_deps' 781773Szelenkov@nginx.com assert findmnt().find(temp_dir) == -1 791622St.nateldemoura@f5.com 801622St.nateldemoura@f5.com isolation['automount']['language_deps'] = True 811622St.nateldemoura@f5.com 821622St.nateldemoura@f5.com self.load('empty', isolation=isolation) 831622St.nateldemoura@f5.com 841773Szelenkov@nginx.com assert findmnt().find(temp_dir) == -1 851622St.nateldemoura@f5.com assert (self.get()['status'] == 200), 'enabled language_deps' 861773Szelenkov@nginx.com assert waitformount(temp_dir), 'language_deps mount' 871773Szelenkov@nginx.com 881773Szelenkov@nginx.com self.conf({"listeners": {}, "applications": {}}) 891773Szelenkov@nginx.com 901773Szelenkov@nginx.com assert waitforunmount(temp_dir), 'language_deps unmount' 91*1774Szelenkov@nginx.com 92*1774Szelenkov@nginx.com def test_python_isolation_procfs(self, is_su, temp_dir): 93*1774Szelenkov@nginx.com isolation_features = option.available['features']['isolation'].keys() 94*1774Szelenkov@nginx.com 95*1774Szelenkov@nginx.com if not is_su: 96*1774Szelenkov@nginx.com pytest.skip('requires root') 97*1774Szelenkov@nginx.com 98*1774Szelenkov@nginx.com isolation = {'rootfs': temp_dir, 'automount': {'procfs': False}} 99*1774Szelenkov@nginx.com 100*1774Szelenkov@nginx.com self.load('ns_inspect', isolation=isolation) 101*1774Szelenkov@nginx.com 102*1774Szelenkov@nginx.com assert ( 103*1774Szelenkov@nginx.com self.getjson(url='/?path=/proc/self')['body']['FileExists'] 104*1774Szelenkov@nginx.com == False 105*1774Szelenkov@nginx.com ), 'no /proc/self' 106*1774Szelenkov@nginx.com 107*1774Szelenkov@nginx.com isolation['automount']['procfs'] = True 108*1774Szelenkov@nginx.com 109*1774Szelenkov@nginx.com self.load('ns_inspect', isolation=isolation) 110*1774Szelenkov@nginx.com 111*1774Szelenkov@nginx.com assert ( 112*1774Szelenkov@nginx.com self.getjson(url='/?path=/proc/self')['body']['FileExists'] == True 113*1774Szelenkov@nginx.com ), '/proc/self' 114