Skip to content

Commit 99a55e5

Browse files
committed
WIP: add chaosmesh debug example with Havoc for local and stage
1 parent 359ea26 commit 99a55e5

File tree

11 files changed

+298
-51
lines changed

11 files changed

+298
-51
lines changed

book/src/framework/components/troubleshooting.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Troubleshooting
22

3+
## Can't start `ctf obs u`
4+
```
5+
Error response from daemon: error while creating mount source path '/host_mnt/Users/fsldkfs/Downloads/compose/conf/provisioning/dashboards/cadvisor/cadvisor.json': mkdir /host_mnt/Users/sdfjskj/Downloads/compose/conf/provisioning: operation not permitted
6+
exit status 1
7+
```
8+
9+
#### Solution
10+
11+
Use another directory with write access or change the directory access
12+
313
## Can't run `anvil`, issue with `Rosetta`
414
```
515
2024/11/27 15:20:27 ⏳ Waiting for container id 79f8a68c07cc image: f4hrenh9it/foundry:latest. Waiting for: &{Port:8546 timeout:0x14000901278 PollInterval:100ms skipInternalCheck:false}

framework/components/clnode/clnode.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var (
3636

3737
// Input represents Chainlink node input
3838
type Input struct {
39+
NoDNS bool `toml:"no_dns"`
3940
DbInput *postgres.Input `toml:"db" validate:"required"`
4041
Node *NodeInput `toml:"node" validate:"required"`
4142
Out *Output `toml:"out"`
@@ -252,6 +253,7 @@ func newNode(in *Input, pgOut *postgres.Output) (*NodeOut, error) {
252253
}
253254
if in.Node.HTTPPort != 0 && in.Node.P2PPort != 0 {
254255
req.HostConfigModifier = func(h *container.HostConfig) {
256+
framework.NoDNS(in.NoDNS, h)
255257
h.PortBindings = portBindings
256258
framework.ResourceLimitsFunc(h, in.Node.ContainerResources)
257259
}

framework/components/jd/jd.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type Input struct {
2929
DockerFilePath string `toml:"docker_file"`
3030
DockerContext string `toml:"docker_ctx"`
3131
DBInput *postgres.Input `toml:"db"`
32+
NoDNS bool `toml:"no_dns"`
3233
Out *Output `toml:"out"`
3334
}
3435

@@ -93,6 +94,8 @@ func NewJD(in *Input) (*Output, error) {
9394
},
9495
ExposedPorts: []string{bindPort},
9596
HostConfigModifier: func(h *container.HostConfig) {
97+
// JobDistributor service must be isolated from internet by default!
98+
framework.NoDNS(true, h)
9699
h.PortBindings = framework.MapTheSamePort(bindPort)
97100
},
98101
Env: map[string]string{
@@ -104,21 +107,6 @@ func NewJD(in *Input) (*Output, error) {
104107
WaitingFor: tcwait.ForAll(
105108
tcwait.ForListeningPort(nat.Port(fmt.Sprintf("%s/tcp", in.GRPCPort))),
106109
),
107-
LifecycleHooks: []tc.ContainerLifecycleHooks{
108-
{
109-
PostStarts: []tc.ContainerHook{
110-
func(ctx context.Context, c tc.Container) error {
111-
_, _, err := c.Exec(ctx, []string{
112-
"sh", "-c", `iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT && \
113-
iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT && \
114-
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT && \
115-
iptables -A OUTPUT -j DROP`,
116-
})
117-
return err
118-
},
119-
},
120-
},
121-
},
122110
}
123111
if req.Image == "" {
124112
req.Image = TmpImageName
Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package networktest
22

3+
/*
4+
This component exists purely for Docker debug purposes
5+
*/
6+
37
import (
48
"context"
59
"fmt"
@@ -11,18 +15,18 @@ import (
1115
"github.com/smartcontractkit/chainlink-testing-framework/framework"
1216
)
1317

14-
type AlpineInput struct {
15-
Privileged bool // Whether to run in privileged mode
16-
BlockInternet bool // Whether to block internet access
17-
Labels map[string]string // Container labels
18+
type Input struct {
19+
Name string
20+
NoDNS bool
21+
CustomNetwork bool
1822
}
1923

20-
type AlpineOutput struct{}
24+
type Output struct{}
2125

2226
// NewNetworkTest creates a minimal Alpine Linux container for network testing
23-
func NewNetworkTest(in AlpineInput) (*AlpineOutput, error) {
27+
func NewNetworkTest(in Input) error {
2428
req := testcontainers.ContainerRequest{
25-
Name: "networktest",
29+
Name: in.Name,
2630
Image: "alpine:latest",
2731
Networks: []string{framework.DefaultNetworkName},
2832
NetworkAliases: map[string][]string{
@@ -32,39 +36,17 @@ func NewNetworkTest(in AlpineInput) (*AlpineOutput, error) {
3236
WaitingFor: wait.ForLog(""),
3337
Cmd: []string{"/bin/sh", "-c", "while true; do sleep 30; done;"},
3438
}
35-
36-
if in.BlockInternet {
37-
req.HostConfigModifier = func(hc *container.HostConfig) {
38-
hc.DNS = []string{"127.0.0.1"}
39-
hc.CapAdd = []string{"NET_ADMIN"}
40-
if in.Privileged {
41-
hc.Privileged = true
42-
}
43-
}
44-
45-
req.LifecycleHooks = []testcontainers.ContainerLifecycleHooks{{
46-
PostStarts: []testcontainers.ContainerHook{
47-
func(ctx context.Context, c testcontainers.Container) error {
48-
// Block all internet traffic while allowing local network
49-
_, _, err := c.Exec(ctx, []string{
50-
"sh", "-c", `iptables -A OUTPUT -d 10.0.0.0/8 -j ACCEPT &&
51-
iptables -A OUTPUT -d 172.16.0.0/12 -j ACCEPT &&
52-
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT &&
53-
iptables -A OUTPUT -j DROP`,
54-
})
55-
return err
56-
},
57-
},
58-
}}
39+
req.HostConfigModifier = func(hc *container.HostConfig) {
40+
// Remove external DNS
41+
framework.NoDNS(in.NoDNS, hc)
5942
}
6043

6144
_, err := testcontainers.GenericContainer(context.Background(), testcontainers.GenericContainerRequest{
6245
ContainerRequest: req,
6346
Started: true,
6447
})
6548
if err != nil {
66-
return nil, fmt.Errorf("failed to start alpine container: %w", err)
49+
return fmt.Errorf("failed to start alpine container: %w", err)
6750
}
68-
69-
return &AlpineOutput{}, nil
51+
return nil
7052
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package networktest_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
9+
"github.com/smartcontractkit/chainlink-testing-framework/framework"
10+
"github.com/smartcontractkit/chainlink-testing-framework/framework/components/networktest"
11+
)
12+
13+
func TestNetworkIsolationRules(t *testing.T) {
14+
t.Run("can work without DNS isolation", func(t *testing.T) {
15+
name := "nettest1"
16+
err := networktest.NewNetworkTest(networktest.Input{NoDNS: false, Name: name})
17+
require.NoError(t, err)
18+
dc, err := framework.NewDockerClient()
19+
require.NoError(t, err)
20+
sOut, err := dc.ExecContainer(name, []string{"ping", "-c", "1", "google.com"})
21+
require.NoError(t, err)
22+
require.NotContains(t, sOut, "bad address")
23+
fmt.Println(sOut)
24+
})
25+
t.Run("DNS isolation works", func(t *testing.T) {
26+
name := "nettest2"
27+
err := networktest.NewNetworkTest(networktest.Input{NoDNS: true, Name: name})
28+
require.NoError(t, err)
29+
dc, err := framework.NewDockerClient()
30+
require.NoError(t, err)
31+
sOut, err := dc.ExecContainer(name, []string{"ping", "-c", "1", "google.com"})
32+
require.NoError(t, err)
33+
require.Contains(t, sOut, "bad address")
34+
fmt.Println(sOut)
35+
})
36+
}

framework/components/simple_node_set/node_set.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Input struct {
3030
OverrideMode string `toml:"override_mode" validate:"required,oneof=all each"`
3131
DbInput *postgres.Input `toml:"db" validate:"required"`
3232
NodeSpecs []*clnode.Input `toml:"node_specs" validate:"required"`
33+
NoDNS bool `toml:"no_dns"`
3334
Out *Output `toml:"out"`
3435
}
3536

framework/docker.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ func ResourceLimitsFunc(h *container.HostConfig, resources *ContainerResources)
412412
}
413413
}
414414

415+
// GenerateCustomPortsData generate custom ports data: exposed and forwarded port map
415416
func GenerateCustomPortsData(portsProvided []string) ([]string, nat.PortMap, error) {
416417
exposedPorts := make([]string, 0)
417418
portBindings := nat.PortMap{}
@@ -438,3 +439,10 @@ func GenerateCustomPortsData(portsProvided []string) ([]string, nat.PortMap, err
438439
exposedPorts = append(exposedPorts, customPorts...)
439440
return exposedPorts, portBindings, nil
440441
}
442+
443+
// NoDNS removes default DNS server and sets it to localhost
444+
func NoDNS(noDNS bool, hc *container.HostConfig) {
445+
if noDNS {
446+
hc.DNS = []string{"127.0.0.1"}
447+
}
448+
}

framework/examples/myproject/smoke_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestSmoke(t *testing.T) {
3535
_, err = jd.NewJD(in.JD)
3636
require.NoError(t, err)
3737
spew.Dump(in.NodeSets[0])
38-
_, err = networktest.NewNetworkTest(networktest.AlpineInput{Privileged: true, BlockInternet: true})
38+
_, err = networktest.NewNetworkTest(networktest.Input{Privileged: true, BlockInternet: true})
3939
require.NoError(t, err)
4040
dc, err := framework.NewDockerClient()
4141
require.NoError(t, err)

framework/examples/myproject_cll/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ docker build -t job-distributor:0.9.0 -f e2e/Dockerfile.e2e .
1212
Run the tests locally
1313
```
1414
CTF_CONFIGS=jd.toml go test -v -count 1 -run TestJD
15+
CTF_CONFIGS=jd_fork.toml go test -v -count 1 -run TestJDFork
1516
```

framework/examples/myproject_cll/go.mod

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ replace (
88
)
99

1010
require (
11+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
1112
github.com/smartcontractkit/chainlink-testing-framework/framework v0.0.0-00010101000000-000000000000
1213
github.com/stretchr/testify v1.10.0
1314
)
@@ -16,6 +17,8 @@ require (
1617
dario.cat/mergo v1.0.1 // indirect
1718
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
1819
github.com/Microsoft/go-winio v0.6.2 // indirect
20+
github.com/StackExchange/wmi v1.2.1 // indirect
21+
github.com/avast/retry-go/v4 v4.6.1 // indirect
1922
github.com/aws/aws-sdk-go-v2 v1.32.5 // indirect
2023
github.com/aws/aws-sdk-go-v2/config v1.28.4 // indirect
2124
github.com/aws/aws-sdk-go-v2/credentials v1.17.45 // indirect
@@ -30,41 +33,65 @@ require (
3033
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.4 // indirect
3134
github.com/aws/aws-sdk-go-v2/service/sts v1.33.0 // indirect
3235
github.com/aws/smithy-go v1.22.1 // indirect
36+
github.com/bits-and-blooms/bitset v1.17.0 // indirect
3337
github.com/block-vision/sui-go-sdk v1.0.6 // indirect
38+
github.com/bytedance/sonic v1.12.3 // indirect
39+
github.com/bytedance/sonic/loader v0.2.0 // indirect
3440
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
41+
github.com/cloudwego/base64x v0.1.4 // indirect
42+
github.com/cloudwego/iasm v0.2.0 // indirect
43+
github.com/consensys/bavard v0.1.22 // indirect
44+
github.com/consensys/gnark-crypto v0.14.0 // indirect
3545
github.com/containerd/log v0.1.0 // indirect
3646
github.com/containerd/platforms v0.2.1 // indirect
3747
github.com/cpuguy83/dockercfg v0.3.2 // indirect
38-
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
48+
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
49+
github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect
50+
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
51+
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
3952
github.com/distribution/reference v0.6.0 // indirect
4053
github.com/docker/docker v28.0.1+incompatible // indirect
4154
github.com/docker/go-connections v0.5.0 // indirect
4255
github.com/docker/go-units v0.5.0 // indirect
4356
github.com/ebitengine/purego v0.8.2 // indirect
57+
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
58+
github.com/ethereum/go-ethereum v1.15.0 // indirect
59+
github.com/ethereum/go-verkle v0.2.2 // indirect
4460
github.com/felixge/httpsnoop v1.0.4 // indirect
61+
github.com/fsnotify/fsnotify v1.6.0 // indirect
4562
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
63+
github.com/gin-contrib/sse v0.1.0 // indirect
64+
github.com/gin-gonic/gin v1.10.0 // indirect
4665
github.com/go-logr/logr v1.4.2 // indirect
4766
github.com/go-logr/stdr v1.2.2 // indirect
4867
github.com/go-ole/go-ole v1.3.0 // indirect
4968
github.com/go-playground/locales v0.14.1 // indirect
5069
github.com/go-playground/universal-translator v0.18.1 // indirect
5170
github.com/go-playground/validator/v10 v10.22.1 // indirect
5271
github.com/go-resty/resty/v2 v2.15.3 // indirect
72+
github.com/goccy/go-json v0.10.3 // indirect
5373
github.com/gogo/protobuf v1.3.2 // indirect
5474
github.com/google/uuid v1.6.0 // indirect
75+
github.com/gorilla/websocket v1.5.1 // indirect
5576
github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect
77+
github.com/holiman/uint256 v1.3.2 // indirect
78+
github.com/json-iterator/go v1.1.12 // indirect
5679
github.com/klauspost/compress v1.17.9 // indirect
80+
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
5781
github.com/leodido/go-urn v1.4.0 // indirect
5882
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
5983
github.com/magiconair/properties v1.8.9 // indirect
6084
github.com/mattn/go-colorable v0.1.13 // indirect
6185
github.com/mattn/go-isatty v0.0.20 // indirect
86+
github.com/mmcloughlin/addchain v0.4.0 // indirect
6287
github.com/moby/docker-image-spec v1.3.1 // indirect
6388
github.com/moby/patternmatcher v0.6.0 // indirect
6489
github.com/moby/sys/sequential v0.5.0 // indirect
6590
github.com/moby/sys/user v0.1.0 // indirect
6691
github.com/moby/sys/userns v0.1.0 // indirect
6792
github.com/moby/term v0.5.0 // indirect
93+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
94+
github.com/modern-go/reflect2 v1.0.2 // indirect
6895
github.com/morikuni/aec v1.0.0 // indirect
6996
github.com/opencontainers/go-digest v1.0.0 // indirect
7097
github.com/opencontainers/image-spec v1.1.1 // indirect
@@ -73,14 +100,18 @@ require (
73100
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
74101
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
75102
github.com/rs/zerolog v1.33.0 // indirect
103+
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
76104
github.com/shirou/gopsutil/v4 v4.25.1 // indirect
77105
github.com/sirupsen/logrus v1.9.3 // indirect
106+
github.com/supranational/blst v0.3.13 // indirect
78107
github.com/testcontainers/testcontainers-go v0.36.0 // indirect
79108
github.com/tidwall/gjson v1.14.4 // indirect
80109
github.com/tidwall/match v1.1.1 // indirect
81110
github.com/tidwall/pretty v1.2.0 // indirect
82111
github.com/tklauser/go-sysconf v0.3.12 // indirect
83112
github.com/tklauser/numcpus v0.6.1 // indirect
113+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
114+
github.com/ugorji/go/codec v1.2.12 // indirect
84115
github.com/yusufpapurcu/wmi v1.2.4 // indirect
85116
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
86117
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
@@ -90,7 +121,9 @@ require (
90121
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
91122
go.opentelemetry.io/otel/trace v1.35.0 // indirect
92123
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
124+
golang.org/x/arch v0.11.0 // indirect
93125
golang.org/x/crypto v0.32.0 // indirect
126+
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
94127
golang.org/x/net v0.34.0 // indirect
95128
golang.org/x/sync v0.10.0 // indirect
96129
golang.org/x/sys v0.31.0 // indirect
@@ -100,5 +133,7 @@ require (
100133
google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect
101134
google.golang.org/grpc v1.68.0 // indirect
102135
google.golang.org/protobuf v1.36.1 // indirect
136+
gopkg.in/guregu/null.v4 v4.0.0 // indirect
103137
gopkg.in/yaml.v3 v3.0.1 // indirect
138+
rsc.io/tmplfunc v0.0.3 // indirect
104139
)

0 commit comments

Comments
 (0)