1*1654Szelenkov@nginx.comimport shutil 2*1654Szelenkov@nginx.com 31596Szelenkov@nginx.comimport pytest 41490St.nateldemoura@f5.com 5*1654Szelenkov@nginx.comfrom conftest import option 6*1654Szelenkov@nginx.comfrom conftest import unit_run 7*1654Szelenkov@nginx.comfrom conftest import unit_stop 81490St.nateldemoura@f5.comfrom unit.applications.lang.python import TestApplicationPython 91490St.nateldemoura@f5.comfrom unit.feature.isolation import TestFeatureIsolation 101490St.nateldemoura@f5.com 111490St.nateldemoura@f5.com 121490St.nateldemoura@f5.comclass TestPythonIsolation(TestApplicationPython): 131490St.nateldemoura@f5.com prerequisites = {'modules': {'python': 'any'}, 'features': ['isolation']} 141490St.nateldemoura@f5.com 151490St.nateldemoura@f5.com @classmethod 161596Szelenkov@nginx.com def setup_class(cls, complete_check=True): 17*1654Szelenkov@nginx.com check = super().setup_class(complete_check=False) 181490St.nateldemoura@f5.com 19*1654Szelenkov@nginx.com unit = unit_run() 20*1654Szelenkov@nginx.com option.temp_dir = unit['temp_dir'] 21*1654Szelenkov@nginx.com 22*1654Szelenkov@nginx.com TestFeatureIsolation().check(option.available, unit['temp_dir']) 231490St.nateldemoura@f5.com 24*1654Szelenkov@nginx.com assert unit_stop() is None 25*1654Szelenkov@nginx.com shutil.rmtree(unit['temp_dir']) 261490St.nateldemoura@f5.com 27*1654Szelenkov@nginx.com return check if not complete_check else check() 28*1654Szelenkov@nginx.com 29*1654Szelenkov@nginx.com def test_python_isolation_rootfs(self, is_su, temp_dir): 30*1654Szelenkov@nginx.com isolation_features = option.available['features']['isolation'].keys() 311490St.nateldemoura@f5.com 321490St.nateldemoura@f5.com if 'mnt' not in isolation_features: 331596Szelenkov@nginx.com pytest.skip('requires mnt ns') 341490St.nateldemoura@f5.com 351596Szelenkov@nginx.com if not is_su: 361490St.nateldemoura@f5.com if 'user' not in isolation_features: 371596Szelenkov@nginx.com pytest.skip('requires unprivileged userns or root') 381490St.nateldemoura@f5.com 391490St.nateldemoura@f5.com if not 'unprivileged_userns_clone' in isolation_features: 401596Szelenkov@nginx.com pytest.skip('requires unprivileged userns or root') 411490St.nateldemoura@f5.com 421490St.nateldemoura@f5.com isolation = { 431596Szelenkov@nginx.com 'namespaces': {'credential': not is_su, 'mount': True}, 44*1654Szelenkov@nginx.com 'rootfs': temp_dir, 451490St.nateldemoura@f5.com } 461490St.nateldemoura@f5.com 471490St.nateldemoura@f5.com self.load('empty', isolation=isolation) 481490St.nateldemoura@f5.com 491596Szelenkov@nginx.com assert self.get()['status'] == 200, 'python rootfs' 501490St.nateldemoura@f5.com 511490St.nateldemoura@f5.com self.load('ns_inspect', isolation=isolation) 521490St.nateldemoura@f5.com 531596Szelenkov@nginx.com assert ( 54*1654Szelenkov@nginx.com self.getjson(url='/?path=' + temp_dir)['body']['FileExists'] 551596Szelenkov@nginx.com == False 561596Szelenkov@nginx.com ), 'temp_dir does not exists in rootfs' 571490St.nateldemoura@f5.com 581596Szelenkov@nginx.com assert ( 591596Szelenkov@nginx.com self.getjson(url='/?path=/proc/self')['body']['FileExists'] 601596Szelenkov@nginx.com == False 611596Szelenkov@nginx.com ), 'no /proc/self' 621490St.nateldemoura@f5.com 631596Szelenkov@nginx.com assert ( 641596Szelenkov@nginx.com self.getjson(url='/?path=/dev/pts')['body']['FileExists'] == False 651596Szelenkov@nginx.com ), 'no /dev/pts' 661596Szelenkov@nginx.com 671596Szelenkov@nginx.com assert ( 681596Szelenkov@nginx.com self.getjson(url='/?path=/sys/kernel')['body']['FileExists'] 691596Szelenkov@nginx.com == False 701596Szelenkov@nginx.com ), 'no /sys/kernel' 711490St.nateldemoura@f5.com 721490St.nateldemoura@f5.com ret = self.getjson(url='/?path=/app/python/ns_inspect') 731490St.nateldemoura@f5.com 741596Szelenkov@nginx.com assert ( 751596Szelenkov@nginx.com ret['body']['FileExists'] == True 761596Szelenkov@nginx.com ), 'application exists in rootfs' 771622St.nateldemoura@f5.com 78*1654Szelenkov@nginx.com def test_python_isolation_rootfs_no_language_deps(self, is_su, temp_dir): 79*1654Szelenkov@nginx.com isolation_features = option.available['features']['isolation'].keys() 801622St.nateldemoura@f5.com 811622St.nateldemoura@f5.com if 'mnt' not in isolation_features: 821622St.nateldemoura@f5.com pytest.skip('requires mnt ns') 831622St.nateldemoura@f5.com 841622St.nateldemoura@f5.com if not is_su: 851622St.nateldemoura@f5.com if 'user' not in isolation_features: 861622St.nateldemoura@f5.com pytest.skip('requires unprivileged userns or root') 871622St.nateldemoura@f5.com 881622St.nateldemoura@f5.com if not 'unprivileged_userns_clone' in isolation_features: 891622St.nateldemoura@f5.com pytest.skip('requires unprivileged userns or root') 901622St.nateldemoura@f5.com 911622St.nateldemoura@f5.com isolation = { 921622St.nateldemoura@f5.com 'namespaces': {'credential': not is_su, 'mount': True}, 93*1654Szelenkov@nginx.com 'rootfs': temp_dir, 941622St.nateldemoura@f5.com 'automount': {'language_deps': False} 951622St.nateldemoura@f5.com } 961622St.nateldemoura@f5.com 971622St.nateldemoura@f5.com self.load('empty', isolation=isolation) 981622St.nateldemoura@f5.com 991622St.nateldemoura@f5.com assert (self.get()['status'] != 200), 'disabled language_deps' 1001622St.nateldemoura@f5.com 1011622St.nateldemoura@f5.com isolation['automount']['language_deps'] = True 1021622St.nateldemoura@f5.com 1031622St.nateldemoura@f5.com self.load('empty', isolation=isolation) 1041622St.nateldemoura@f5.com 1051622St.nateldemoura@f5.com assert (self.get()['status'] == 200), 'enabled language_deps' 106