summaryrefslogblamecommitdiffhomepage
path: root/test/unit/check/isolation.py
blob: 861c0818137828d4e30637e52f61a42ba378b710 (plain) (tree)
1
2
3
4
5
6
7
8
           
                        
 




                                                       



                                                     
              
 
 
                      



                                    
                                                   

                
                                                                    



                                              

                                                                       






                                                                      
                                                                    



                                              

                                                                           







                                                                      
                                                                      



                                              

                                                                          






                                                                      
                                              
 
                
                                                                    



                                              

                                                                         





                                                                      
                                              

                
                                                                    

                             
                                                               

                                              

                                                                          





                                                                      
                                              

                
                                                                    



                                              
                                                                   







                                                                      
                                                                         



                                              

                                                                              





                                                                      
                    



                         
                                                    


                              
                                     
                    


                          
                    
 
                                
 





                                                                   



                            


                                    
import json
from pathlib import Path

from unit.applications.lang.go import ApplicationGo
from unit.applications.lang.java import ApplicationJava
from unit.applications.lang.node import ApplicationNode
from unit.applications.lang.ruby import ApplicationRuby
from unit.http import HTTP1
from unit.option import option
from unit.utils import getns

allns = ['pid', 'mnt', 'ipc', 'uts', 'cgroup', 'net']
http = HTTP1()


def check_isolation():
    available = option.available

    conf = ''
    if 'go' in available['modules']:
        ApplicationGo().prepare_env('empty', 'app')

        conf = {
            "listeners": {"*:8080": {"pass": "applications/empty"}},
            "applications": {
                "empty": {
                    "type": "external",
                    "processes": {"spare": 0},
                    "working_directory": f"{option.test_dir}/go/empty",
                    "executable": f"{option.test_dir}/go/app",
                    "isolation": {"namespaces": {"credential": True}},
                },
            },
        }

    elif 'python' in available['modules']:
        conf = {
            "listeners": {"*:8080": {"pass": "applications/empty"}},
            "applications": {
                "empty": {
                    "type": "python",
                    "processes": {"spare": 0},
                    "path": f"{option.test_dir}/python/empty",
                    "working_directory": f"{option.test_dir}/python/empty",
                    "module": "wsgi",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    elif 'php' in available['modules']:
        conf = {
            "listeners": {"*:8080": {"pass": "applications/phpinfo"}},
            "applications": {
                "phpinfo": {
                    "type": "php",
                    "processes": {"spare": 0},
                    "root": f"{option.test_dir}/php/phpinfo",
                    "working_directory": f"{option.test_dir}/php/phpinfo",
                    "index": "index.php",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    elif 'ruby' in available['modules']:
        ApplicationRuby().prepare_env('empty')

        conf = {
            "listeners": {"*:8080": {"pass": "applications/empty"}},
            "applications": {
                "empty": {
                    "type": "ruby",
                    "processes": {"spare": 0},
                    "working_directory": f"{option.temp_dir}/ruby/empty",
                    "script": f"{option.temp_dir}/ruby/empty/config.ru",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    elif 'java' in available['modules']:
        ApplicationJava().prepare_env('empty')

        conf = {
            "listeners": {"*:8080": {"pass": "applications/empty"}},
            "applications": {
                "empty": {
                    "unit_jars": f"{option.current_dir}/build",
                    "type": "java",
                    "processes": {"spare": 0},
                    "working_directory": f"{option.temp_dir}/java/empty/",
                    "webapp": f"{option.temp_dir}/java",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    elif 'node' in available['modules']:
        ApplicationNode().prepare_env('basic')

        conf = {
            "listeners": {"*:8080": {"pass": "applications/basic"}},
            "applications": {
                "basic": {
                    "type": "external",
                    "processes": {"spare": 0},
                    "working_directory": f"{option.temp_dir}/node",
                    "executable": "app.js",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    elif 'perl' in available['modules']:
        conf = {
            "listeners": {"*:8080": {"pass": "applications/body_empty"}},
            "applications": {
                "body_empty": {
                    "type": "perl",
                    "processes": {"spare": 0},
                    "working_directory": f"{option.test_dir}/perl/body_empty",
                    "script": f"{option.test_dir}/perl/body_empty/psgi.pl",
                    "isolation": {"namespaces": {"credential": True}},
                }
            },
        }

    else:
        return False

    resp = http.put(
        url='/config',
        sock_type='unix',
        addr=f'{option.temp_dir}/control.unit.sock',
        body=json.dumps(conf),
    )

    if 'success' not in resp['body']:
        return False

    userns = getns('user')
    if not userns:
        return False

    isolation = {'user': userns}

    path_clone = Path('/proc/sys/kernel/unprivileged_userns_clone')
    if (
        path_clone.exists()
        and path_clone.read_text(encoding='utf-8').rstrip() == '1'
    ):
        isolation['unprivileged_userns_clone'] = True

    for ns in allns:
        ns_value = getns(ns)
        if ns_value:
            isolation[ns] = ns_value

    return isolation