1import os 2import shutil 3import subprocess 4 5from unit.applications.proto import ApplicationProto 6from unit.option import option 7 8 9class ApplicationGo(ApplicationProto): 10 @staticmethod 11 def prepare_env(script, name='app', static=False): 12 try: 13 subprocess.check_output(['which', 'go']) 14 except subprocess.CalledProcessError: 15 return None 16 17 temp_dir = f'{option.temp_dir}/go/' 18 19 if not os.path.exists(temp_dir): 20 os.mkdir(temp_dir) 21 22 cache_dir = f'{option.cache_dir}/go-build' 23 24 if not os.path.exists(cache_dir): 25 os.mkdir(cache_dir) 26 27 env = os.environ.copy() 28 env['GOPATH'] = f'{option.current_dir}/build/go' 29 env['GOCACHE'] = cache_dir 30 31 shutil.copy2(f'{option.test_dir}/go/{script}/{name}.go', temp_dir) 32 33 if static: 34 args = [ 35 'go', 36 'build', 37 '-tags', 38 'netgo', 39 '-ldflags', 40 '-extldflags "-static"', 41 '-o', 42 f'{temp_dir}{name}', 43 f'{temp_dir}{name}.go', 44 ] 45 else: 46 args = [ 47 'go', 48 'build', 49 '-o', 50 f'{temp_dir}{name}', 51 f'{temp_dir}{name}.go', 52 ] 53 54 replace_path = f'{option.current_dir}/build/go/src/unit.nginx.org/go' 55 56 with open(f'{temp_dir}go.mod', 'w', encoding='utf-8') as f: 57 f.write( 58 f"""module test/app 59require unit.nginx.org/go v0.0.0 60replace unit.nginx.org/go => {replace_path} 61""" 62 ) 63 64 if option.detailed: 65 print(f'\n$ GOPATH={env["GOPATH"]} {" ".join(args)}') 66 67 try: 68 output = subprocess.check_output( 69 args, env=env, cwd=temp_dir, stderr=subprocess.STDOUT 70 ) 71 72 except KeyboardInterrupt: 73 raise 74 75 except subprocess.CalledProcessError: 76 return None 77 78 return output 79 80 def load(self, script, name='app', **kwargs): 81 static_build = False 82 83 wdir = f'{option.test_dir}/go/{script}' 84 executable = f'{option.temp_dir}/go/{name}' 85 86 if 'isolation' in kwargs and 'rootfs' in kwargs['isolation']: 87 wdir = "/go/" 88 executable = f"/go/{name}" 89 static_build = True 90 91 ApplicationGo.prepare_env(script, name, static=static_build) 92 93 conf = { 94 "listeners": {"*:8080": {"pass": f"applications/{script}"}}, 95 "applications": { 96 script: { 97 "type": "external", 98 "processes": {"spare": 0}, 99 "working_directory": wdir, 100 "executable": executable, 101 }, 102 }, 103 } 104 105 self._load_conf(conf, **kwargs) 106