python.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package python
  2. import (
  3. _ "embed"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. "strings"
  8. "syscall"
  9. "time"
  10. "github.com/google/uuid"
  11. "github.com/langgenius/dify-sandbox/internal/core/runner"
  12. "github.com/langgenius/dify-sandbox/internal/static"
  13. )
  14. type PythonRunner struct {
  15. runner.Runner
  16. runner.SeccompRunner
  17. }
  18. //go:embed prescript.py
  19. var python_sandbox_fs []byte
  20. //go:embed python.so
  21. var python_lib []byte
  22. func (p *PythonRunner) Run(code string, timeout time.Duration, stdin chan []byte) (<-chan []byte, <-chan []byte, error) {
  23. // check if libpython.so exists
  24. if _, err := os.Stat("/tmp/sandbox-python/python.so"); os.IsNotExist(err) {
  25. err := os.MkdirAll("/tmp/sandbox-python", 0755)
  26. if err != nil {
  27. return nil, nil, err
  28. }
  29. err = os.WriteFile("/tmp/sandbox-python/python.so", python_lib, 0755)
  30. if err != nil {
  31. return nil, nil, err
  32. }
  33. }
  34. // create a tmp dir and copy the python script
  35. temp_code_name := strings.ReplaceAll(uuid.New().String(), "-", "_")
  36. temp_code_name = strings.ReplaceAll(temp_code_name, "/", ".")
  37. temp_code_path := fmt.Sprintf("/tmp/code/%s.py", temp_code_name)
  38. err := os.MkdirAll("/tmp/code", 0755)
  39. if err != nil {
  40. return nil, nil, err
  41. }
  42. defer os.Remove(temp_code_path)
  43. err = os.WriteFile(temp_code_path, []byte(code), 0755)
  44. if err != nil {
  45. return nil, nil, err
  46. }
  47. err = p.WithTempDir([]string{
  48. temp_code_path,
  49. "/tmp/sandbox-python/python.so",
  50. }, func() error {
  51. syscall.Exec("/usr/bin/python3", []string{
  52. "/usr/bin/python3",
  53. "-c",
  54. string(python_sandbox_fs),
  55. temp_code_path,
  56. strconv.Itoa(static.SANDBOX_USER_UID),
  57. strconv.Itoa(static.SANDBOX_GROUP_ID),
  58. }, nil)
  59. return nil
  60. })
  61. if err != nil {
  62. fmt.Println(err)
  63. }
  64. return nil, nil, nil
  65. }