1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package policytest
import (
"context"
"maps"
"strings"
"sync"
"sync/atomic"
"github.com/johnandersen777/socialweb-computer-kcp/internal/contract/sandbox"
)
const deadProxy = "http://127.0.0.1:9"
type SandboxMode int
const (
SandboxFenced SandboxMode = iota
SandboxUnfenced
SandboxUnavailable
SandboxHung
)
type Sandbox struct {
inner sandbox.Runner
mode atomic.Int32
programs atomic.Int64
actions atomic.Int64
hungMu sync.Mutex
hung chan struct{}
hungOnce *sync.Once
}
func (s *Sandbox) SetMode(mode SandboxMode) {
s.hungMu.Lock()
s.hung, s.hungOnce = make(chan struct{}), &sync.Once{}
s.hungMu.Unlock()
s.mode.Store(int32(mode))
}
func (s *Sandbox) HungStarted() <-chan struct{} {
s.hungMu.Lock()
defer s.hungMu.Unlock()
if s.hung == nil {
s.hung, s.hungOnce = make(chan struct{}), &sync.Once{}
}
return s.hung
}
func (s *Sandbox) Programs() int64 { return s.programs.Load() }
func (s *Sandbox) Actions() int64 { return s.actions.Load() }
func (s *Sandbox) Available() bool {
return SandboxMode(s.mode.Load()) != SandboxUnavailable && s.inner.Available()
}
func (s *Sandbox) Fenced() bool {
return SandboxMode(s.mode.Load()) != SandboxUnfenced && s.inner.Fenced()
}
func (s *Sandbox) Kind() string { return s.inner.Kind() }
func (s *Sandbox) Run(ctx context.Context, p sandbox.Program) (sandbox.Result, error) {
s.programs.Add(1)
if strings.Contains(p.Source, "__PE_RESULT__") {
s.actions.Add(1)
}
if SandboxMode(s.mode.Load()) == SandboxHung {
s.hungMu.Lock()
hung, once := s.hung, s.hungOnce
s.hungMu.Unlock()
if once != nil {
once.Do(func() { close(hung) })
}
<-ctx.Done()
return sandbox.Result{TimedOut: true}, ctx.Err()
}
env := make(map[string]string, len(p.Env)+5)
maps.Copy(env, p.Env)
for _, key := range []string{"HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy"} {
env[key] = deadProxy
}
env["NO_PROXY"] = ""
p.Env = env
return s.inner.Run(ctx, p)
}