package main import ( "encoding/json" "errors" "net" "os" "os/exec" "path/filepath" ) func runMap(conn net.Conn, instance string, objmap map[string]interface{}) (int, error) { program, has := objmap["package"] if !has { return 0, errors.New("a package is required") } arguments, has := objmap["arguments"] if !has { arguments = "" } target, has := objmap["target"] if !has { target = "run" } workdir, has := objmap["workdir"] if !has { return 0, errors.New("a workdir is required") } return run(conn, instance, program.(string), arguments.(string), target.(string), workdir.(string)) } func run(conn net.Conn, instance string, program string, arguments string, target string, workdir string) (int, error) { package_path, err := filepath.Abs(filepath.Join(instance, "apps", program)) if err != nil { return 0, err } var_path, err := filepath.Abs(filepath.Join(instance, "var", program)) if err != nil { return 0, err } info_path, err := filepath.Abs(filepath.Join(package_path, "boundaries.json")) if err != nil { return 0, err } if exists, err := path_exists(info_path); !exists || err != nil { return 0, errors.New("package " + program + " not found") } working_dir, err := filepath.Abs(workdir) if err != nil { return 0, err } infofile_content, err := os.ReadFile(info_path) if err != nil { return 0, err } var info map[string]interface{} err = json.Unmarshal(infofile_content, &info) if err != nil { return 0, err } _, has := info["name"] if !has { return 0, errors.New("invalid boundaries.json file. name field not found") } command_interface, has := info["command"] if !has { return 0, errors.New("invalid boundaries.json file. command field not found") } commands := command_interface.(map[string]interface{}) command, has := commands[target] if !has { return 0, errors.New("target " + target + " not found") } command, err = filepath.Abs(filepath.Join(package_path, command.(string))) if err != nil { return 0, err } env := []string{"APP_DIR=" + package_path, "VAR_DIR=" + var_path} return run_command(conn, command.(string)+" "+arguments, working_dir, env) } func run_command(conn net.Conn, command string, workdir string, env_vars []string) (int, error) { cmd := exec.Command("sh", "-c", command) cmd.Dir = workdir if env_vars != nil { cmd.Env = append(cmd.Environ(), env_vars...) } cmd.Stdout = conn cmd.Stderr = conn cmd.Stdin = conn err := cmd.Start() if err != nil { return 0, err } response := make(map[string]interface{}) response["command"] = "start-command-pipe" response_json, _ := json.Marshal(response) conn.Write(response_json) state, err := cmd.Process.Wait() response["command"] = "end-command-pipe" response["status_code"] = state.ExitCode() response_json, _ = json.Marshal(response) conn.Write(response_json) return state.ExitCode(), err }