1import json 2from pathlib import Path 3 4from unit.applications.lang.go import ApplicationGo 5from unit.applications.lang.java import ApplicationJava 6from unit.applications.lang.node import ApplicationNode 7from unit.applications.lang.ruby import ApplicationRuby 8from unit.http import HTTP1 9from unit.option import option 10from unit.utils import getns 11 12allns = ['pid', 'mnt', 'ipc', 'uts', 'cgroup', 'net'] 13http = HTTP1() 14 15 16def check_isolation(): 17 available = option.available 18 19 conf = '' 20 if 'go' in available['modules']: 21 ApplicationGo().prepare_env('empty', 'app') 22 23 conf = { 24 "listeners": {"*:8080": {"pass": "applications/empty"}}, 25 "applications": { 26 "empty": { 27 "type": "external", 28 "processes": {"spare": 0}, 29 "working_directory": f"{option.test_dir}/go/empty", 30 "executable": f"{option.test_dir}/go/app", 31 "isolation": {"namespaces": {"credential": True}}, 32 }, 33 }, 34 } 35 36 elif 'python' in available['modules']: 37 conf = { 38 "listeners": {"*:8080": {"pass": "applications/empty"}}, 39 "applications": { 40 "empty": { 41 "type": "python", 42 "processes": {"spare": 0}, 43 "path": f"{option.test_dir}/python/empty", 44 "working_directory": f"{option.test_dir}/python/empty", 45 "module": "wsgi", 46 "isolation": {"namespaces": {"credential": True}}, 47 } 48 }, 49 } 50 51 elif 'php' in available['modules']: 52 conf = { 53 "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, 54 "applications": { 55 "phpinfo": { 56 "type": "php", 57 "processes": {"spare": 0}, 58 "root": f"{option.test_dir}/php/phpinfo", 59 "working_directory": f"{option.test_dir}/php/phpinfo", 60 "index": "index.php", 61 "isolation": {"namespaces": {"credential": True}}, 62 } 63 }, 64 } 65 66 elif 'ruby' in available['modules']: 67 ApplicationRuby().prepare_env('empty') 68 69 conf = { 70 "listeners": {"*:8080": {"pass": "applications/empty"}}, 71 "applications": { 72 "empty": { 73 "type": "ruby", 74 "processes": {"spare": 0}, 75 "working_directory": f"{option.temp_dir}/ruby/empty", 76 "script": f"{option.temp_dir}/ruby/empty/config.ru", 77 "isolation": {"namespaces": {"credential": True}}, 78 } 79 }, 80 } 81 82 elif 'java' in available['modules']: 83 ApplicationJava().prepare_env('empty') 84 85 conf = { 86 "listeners": {"*:8080": {"pass": "applications/empty"}}, 87 "applications": { 88 "empty": { 89 "unit_jars": f"{option.current_dir}/build", 90 "type": "java", 91 "processes": {"spare": 0}, 92 "working_directory": f"{option.temp_dir}/java/empty/", 93 "webapp": f"{option.temp_dir}/java", 94 "isolation": {"namespaces": {"credential": True}}, 95 } 96 }, 97 } 98 99 elif 'node' in available['modules']: 100 ApplicationNode().prepare_env('basic') 101 102 conf = { 103 "listeners": {"*:8080": {"pass": "applications/basic"}}, 104 "applications": { 105 "basic": { 106 "type": "external", 107 "processes": {"spare": 0}, 108 "working_directory": f"{option.temp_dir}/node", 109 "executable": "app.js", 110 "isolation": {"namespaces": {"credential": True}}, 111 } 112 }, 113 } 114 115 elif 'perl' in available['modules']: 116 conf = { 117 "listeners": {"*:8080": {"pass": "applications/body_empty"}}, 118 "applications": { 119 "body_empty": { 120 "type": "perl", 121 "processes": {"spare": 0}, 122 "working_directory": f"{option.test_dir}/perl/body_empty", 123 "script": f"{option.test_dir}/perl/body_empty/psgi.pl", 124 "isolation": {"namespaces": {"credential": True}}, 125 } 126 }, 127 } 128 129 else: 130 return False 131 132 resp = http.put( 133 url='/config', 134 sock_type='unix', 135 addr=f'{option.temp_dir}/control.unit.sock', 136 body=json.dumps(conf), 137 ) 138 139 if 'success' not in resp['body']: 140 return False 141 142 userns = getns('user') 143 if not userns: 144 return False 145 146 isolation = {'user': userns} 147 148 path_clone = Path('/proc/sys/kernel/unprivileged_userns_clone') 149 if ( 150 path_clone.exists() 151 and path_clone.read_text(encoding='utf-8').rstrip() == '1' 152 ): 153 isolation['unprivileged_userns_clone'] = True 154 155 for ns in allns: 156 ns_value = getns(ns) 157 if ns_value: 158 isolation[ns] = ns_value 159 160 return isolation 161