Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: stamper #440

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b6ede3d
feat(stamp-funder): initial commit
gacevicljubisa Dec 11, 2024
131ba6f
refactor: improve cmd package and extract stamper to pkg
gacevicljubisa Dec 13, 2024
abaed79
fix(operator): improve logic to use svc port
gacevicljubisa Dec 16, 2024
83a2e40
docs: update readme.md
gacevicljubisa Dec 17, 2024
8f41bb3
feat(stamper): add stamper cmds and implement dilute
gacevicljubisa Dec 17, 2024
efad4e6
feat: add scheduler for periodic checks
gacevicljubisa Dec 18, 2024
06dd4a2
fix(stamper): check error when dilute method invoked
gacevicljubisa Dec 18, 2024
59d5c38
feat: add graceful shutdown
gacevicljubisa Jan 8, 2025
f20121d
wip: add Set and Topup
gacevicljubisa Jan 10, 2025
eb53574
wip: implement topup
gacevicljubisa Jan 10, 2025
6d5e2fa
feat: use beekeeper cluster configuration to get nodes
gacevicljubisa Jan 10, 2025
fa4db7f
fix(stamper): unnecessary conversion
gacevicljubisa Jan 10, 2025
a27ea02
feat: fetch block time
gacevicljubisa Jan 15, 2025
f46cb52
feat(stamper): add topup and set calculations
gacevicljubisa Jan 17, 2025
564c7d1
feat(funder): add periodic check
gacevicljubisa Jan 17, 2025
52e6a64
chore: update readme.md with stamper option
gacevicljubisa Jan 17, 2025
4f00ed7
refactor(cmd): extract getStamper method
gacevicljubisa Jan 17, 2025
c124175
refactor(cmd): extract withTimeoutHandler method
gacevicljubisa Jan 17, 2025
4366d90
feat(stamper): add batch-ids flag to filter per batchID
gacevicljubisa Jan 18, 2025
f6a1948
fix(swap): enable use of url with path for http client
gacevicljubisa Jan 18, 2025
1a27f39
Merge branch 'master' into stamp-funder
gacevicljubisa Jan 18, 2025
5c0769d
fix(stamper): remove parallelization
gacevicljubisa Jan 20, 2025
5fe77b3
fix: calculations
istae Jan 21, 2025
077d60a
refactor(stamper): extract common functions and improve code
gacevicljubisa Jan 21, 2025
828ebd7
fix(stamper): add missing PreRun method
gacevicljubisa Jan 22, 2025
df26666
chore: add log for enable-k8s flag
gacevicljubisa Jan 22, 2025
fe59ee1
refactor(stamper): make small improvements
gacevicljubisa Jan 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ RUN make binary

FROM debian:12.7-slim

ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
ca-certificates; \
Expand Down
221 changes: 192 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,28 @@
- [version](#version)
- [node-funder](#node-funder)
- [node-operator](#node-operator)
- [restart](#restart)
- [stamper](#stamper)
- [Global flags](#global-flags)
- [Public Testnet Checks](#public-testnet-checks)
- [One by one](#one-by-one)
- [All at once, sequentially](#all-at-once-sequentially)

## Introduction

**Ethereum Swarm Beekeeper** is tool used for orchestrating cluster of [Ethereum Swarm Bee](https://github.com/ethersphere/bee) and running integration tests and simulations against it in the Kubernetes.
**Ethereum Swarm Beekeeper** is an orchestration and testing tool for managing [Ethereum Swarm Bee](https://github.com/ethersphere/bee) clusters. It enables:

- **Cluster Management**: Automate creation and deletion of Bee clusters in Kubernetes.
- **Integration Checks**: Run tests (e.g., `pingpong`, `pushsync`) to validate network behavior.
- **Static Endpoints Support**: Execute checks without Kubernetes by using static Bee node endpoints.
- **Node Funding**: Automate funding Bee nodes with ETH and BZZ tokens (Kubernetes optional).
- **Dynamic Configuration**: Use flexible YAML-based configs for customizable actions.

Beekeeper simplifies managing and testing Bee nodes, whether deployed in Kubernetes or standalone environments.

## Requirements

- Kubernetes cluster (v1.19+)
- Kubernetes cluster (v1.31+)
- [Geth Swap node](https://github.com/ethersphere/helm/tree/master/charts/geth-swap)

## Installation
Expand Down Expand Up @@ -92,7 +105,10 @@ If *config-dir* is kept in a Git repo, field *config-git-repo* should point to i

Official GitHub repository with Beekeeper's configuration is **<https://github.com/ethersphere/beekeeper-config>**

NOTE: command flags can be also set through the config file
General Notes:

- command flags can be also set through the config file
- k8s client can be disabled with *enable-k8s* flag (default is true)

## Config directory

Expand Down Expand Up @@ -190,6 +206,8 @@ This setting means that pushsync check can be executed choosing *pushsync-chunks
| version | Print version number |
| node-funder | Fund (top up) Bee nodes |
| node-operator | Auto-funds (top up) Bee nodes on deployment. |
| restart | Restart Bee nodes in Kubernetes |
| stamper | Manage postage batches for nodes |

### check

Expand Down Expand Up @@ -361,22 +379,35 @@ Command **node-funder** uses <https://github.com/ethersphere/node-funder> tool t
It has following flags:

```console
--addresses strings Comma-separated list of Bee node addresses (must start with 0x). Overrides namespace and cluster name.
--geth-url string Endpoint to chain node. Required.
--cluster-name string Cluster name. Ignored if addresses or namespace are set.
--help help for node-funder
--min-native float Minimum amount of chain native coins (xDAI) nodes should have.
--min-swarm float Minimum amount of swarm tokens (xBZZ) nodes should have.
--namespace string Kubernetes namespace. Overrides cluster name if set.
--label-selector string Kubernetes label selector for filtering resources within the specified namespace. An empty string disables filtering, allowing all resources to be selected.
--timeout duration Timeout. (default 5m0s)
--wallet-key string Hex-encoded private key for the Bee node wallet. Required.
--addresses strings Comma-separated list of Bee node addresses (must start with 0x). Overrides namespace and cluster name.
--cluster-name string Name of the Beekeeper cluster to target. Ignored if a namespace is specified.
--geth-url string Endpoint to chain node. Required.
--help help for node-funder
--label-selector string Kubernetes label selector for filtering resources within the specified namespace. Use an empty string to select all resources. (default "beekeeper.ethswarm.org/node-funder=true")
--min-native float Minimum amount of chain native coins (xDAI) nodes should have.
--min-swarm float Minimum amount of swarm tokens (xBZZ) nodes should have.
--namespace string Kubernetes namespace. Overrides cluster name if set.
--periodic-check duration Periodic execution check interval.
--timeout duration Timeout. (default 5m0s)
--wallet-key string Hex-encoded private key for the Bee node wallet. Required.
```

example:
#### Fund specific addresses

```bash
beekeeper node-funder --geth-url="http://geth-swap.default.testnet.internal" --wallet-key="4663c222787e30c1994b59044aa5045377a6e79193a8ead88293926b535c722d" --namespace=default --min-swarm=180 --min-native=2.2 --log-verbosity=3
beekeeper node-funder --geth-url="http://geth-swap.default.testnet.internal" --wallet-key="4663c222787e30c1994b59044aa5045377a6e79193a8ead88293926b535c722d" --addresses=0xf176839c150e52fe30e5c2b5c648465c6fdfa532,0xebe269e07161c68a942a3a7fce6b4ed66867d6f0 --min-swarm=180 --min-native=2.2
```

#### Fund K8S namespace (use label selector to filter nodes)

```bash
beekeeper node-funder --geth-url="http://geth-swap.default.testnet.internal" --wallet-key="4663c222787e30c1994b59044aa5045377a6e79193a8ead88293926b535c722d" --namespace=default --min-swarm=180 --min-native=2.2 --label-selector="app=bee"
```

#### Fund all nodes in the cluster (beekeeper configuration)

```bash
beekeeper node-funder --geth-url="http://geth-swap.default.testnet.internal" --wallet-key="4663c222787e30c1994b59044aa5045377a6e79193a8ead88293926b535c722d" --cluster-name=default --min-swarm=180 --min-native=2.2
```

### node-operator
Expand All @@ -392,7 +423,7 @@ It has following flags:
--min-swarm float Minimum amount of swarm tokens (xBZZ) nodes should have.
--namespace string Kubernetes namespace to scan for scheduled pods.
--label-selector string Kubernetes label selector for filtering resources within the specified namespace. An empty string disables filtering, allowing all resources to be selected.
--timeout duration Timeout. Default is infinite.
--timeout duration Operation timeout (e.g., 5s, 10m, 1.5h). Default is 0, which means no timeout.
--wallet-key string Hex-encoded private key for the Bee node wallet. Required.
```

Expand Down Expand Up @@ -429,26 +460,158 @@ or
beekeeper restart -namespace=default --label-selector="app=bee" --timeout=10m
```

### stamper

Command **stamper** manage postage batches for nodes.

General Notes:

- `namespace` or `cluster-name` must be specified to locate the bee nodes.
- If both are provided, `namespace` takes precedence.
- When `namespace` is set, you can use a `label-selector` to filter specific nodes.
- Use `batch-ids` to target specific postage batches, but this is applied after finding/filtering nodes. If `batch-ids` is not provided, all batches in the filtered nodes are targeted.
- If `timeout` is set to 0 and `periodic-check` is bigger than 0, the operation will run indefinitely with periodic checks.

It has following subcommands:

- **create** - creates a postage batch for selected nodes

It has following flags:

```console
--amount uint Amount of BZZ in PLURS added that the postage batch will have. (default 100000000)
--cluster-name string Target Beekeeper cluster name.
--depth uint16 Batch depth which specifies how many chunks can be signed with the batch. It is a logarithm. Must be higher than default bucket depth (16)
--help help for create
--label-selector string Kubernetes label selector for filtering resources (use empty string for all). (default "beekeeper.ethswarm.org/node-funder=true")
--namespace string Kubernetes namespace (overrides cluster name).
--timeout duration Operation timeout (e.g., 5s, 10m, 1.5h). (default 5m0s)
```

example:

```bash
beekeeper stamper create --cluster-name=default --amount=1000 --depth=16 --timeout=5m
```

or

```bash
beekeeper stamper create --namespace=default --label-selector="app=bee" --amount=1000 --depth=16 --timeout=5m
```

- **topup** - tops up postage batch for selected nodes

It has following flags:

```console
--batch-ids strings Comma separated list of postage batch IDs to top up. If not provided, all batches are topped up.
--cluster-name string Target Beekeeper cluster name.
--geth-url string Geth URL for chain state retrieval.
--help help for topup
--label-selector string Kubernetes label selector for filtering resources (use empty string for all). (default "beekeeper.ethswarm.org/node-funder=true")
--namespace string Kubernetes namespace (overrides cluster name).
--periodic-check duration Periodic check interval. Default is 0, which means no periodic check.
--timeout duration Operation timeout (e.g., 5s, 10m, 1.5h). (default 5m0s)
--topup-to duration Duration to top up the TTL of a stamp to. (default 720h0m0s)
--ttl-threshold duration Threshold for the remaining TTL of a stamp. Actions are triggered when TTL drops below this value. (default 120h0m0s)
```

example:

```bash
beekeeper stamper topup --cluster-name=default --topup-to=720h --ttl-threshold=120h --periodic-check=1h --timeout=24h
```

or

```bash
beekeeper stamper topup --namespace=default --label-selector="app=bee" --topup-to=720h --ttl-threshold=120h --periodic-check=1h --timeout=24h
```

- **dilute** - dilutes postage batch for selected nodes

It has following flags:

```console
--batch-ids strings Comma separated list of postage batch IDs to dilute. If not provided, all batches are diluted.
--cluster-name string Target Beekeeper cluster name.
--dilution-depth uint8 Number of levels by which to increase the depth of a stamp during dilution. (default 1)
--help help for dilute
--label-selector string Kubernetes label selector for filtering resources (use empty string for all). (default "beekeeper.ethswarm.org/node-funder=true")
--namespace string Kubernetes namespace (overrides cluster name).
--periodic-check duration Periodic check interval. Default is 0, which means no periodic check.
--timeout duration Operation timeout (e.g., 5s, 10m, 1.5h). (default 5m0s)
--usage-threshold float Percentage threshold for stamp utilization. Triggers dilution when usage exceeds this value. (default 90)
```

example:

```bash
beekeeper stamper dilute --cluster-name=default --dilution-depth=1 --usage-threshold=90 --periodic-check=1h --timeout=24h
```

or

```bash
beekeeper stamper dilute --namespace=default --label-selector="app=bee" --dilution-depth=1 --usage-threshold=90 --periodic-check=1h --timeout=24h
```

- **set** - sets postage batch for selected nodes

It has following flags:

```console
--batch-ids strings Comma separated list of postage batch IDs to set. If not provided, all batches are set.
--cluster-name string Target Beekeeper cluster name.
--dilution-depth uint16 Number of levels by which to increase the depth of a stamp during dilution. (default 1)
--geth-url string Geth URL for chain state retrieval.
--help help for set
--label-selector string Kubernetes label selector for filtering resources (use empty string for all). (default "beekeeper.ethswarm.org/node-funder=true")
--namespace string Kubernetes namespace (overrides cluster name).
--periodic-check duration Periodic check interval. Default is 0, which means no periodic check.
--timeout duration Operation timeout (e.g., 5s, 10m, 1.5h). (default 5m0s)
--topup-to duration Duration to top up the TTL of a stamp to. (default 720h0m0s)
--ttl-threshold duration Threshold for the remaining TTL of a stamp. Actions are triggered when TTL drops below this value. (default 120h0m0s)
--usage-threshold float Percentage threshold for stamp utilization. Triggers dilution when usage exceeds this value. (default 90)
```

example:

```bash
beekeeper stamper set --cluster-name=default --dilution-depth=1 --usage-threshold=90 --ttl-threshold=120h --topup-to=720h --periodic-check=1h --timeout=24h
```

or

```bash
beekeeper stamper set --namespace=default --label-selector="app=bee" --dilution-depth=1 --usage-threshold=90 --ttl-threshold=120h --topup-to=720h --periodic-check=1h --timeout=24h
```

## Global flags

Global flags can be used with any command.

example:

```console
--config string config file (default is $HOME/.beekeeper.yaml)
--config-dir string config directory (default is $HOME/.beekeeper/)
--config-git-branch string Git branch (default "main")
--config-git-password string Git password or personal access tokens (needed for private repos)
--config-git-repo string Git repository with configurations (uses config directory when Git repo is not specified) (default "")
--config-git-username string Git username (needed for private repos)
--log-verbosity string log verbosity level 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace (default "info")
--loki-endpoint string loki http endpoint for pushing local logs (use http://loki.testnet.internal/loki/api/v1/push)
--tracing-enable enable tracing
--tracing-endpoint string endpoint to send tracing data (default "tempo-tempo-distributed-distributor.observability:6831")
--tracing-host string host to send tracing data
--tracing-port string port to send tracing data
--tracing-service-name string service name identifier for tracing (default "beekeeper")
--config string Path to the configuration file (default is $HOME/.beekeeper.yaml)
--config-dir string Directory for configuration files (default "C:\\Users\\ljubi\\.beekeeper")
--config-git-branch string Git branch to use for configuration files (default "main")
--config-git-dir string Directory within the Git repository containing configuration files. Defaults to the root directory (default ".")
--config-git-password string Git password or personal access token for authentication (required for private repositories)
--config-git-repo string URL of the Git repository containing configuration files (uses the config-dir if not specified)
--config-git-username string Git username for authentication (required for private repositories)
--enable-k8s Enable Kubernetes client functionality (default true)
--in-cluster Use the in-cluster Kubernetes client
--kubeconfig string Path to the kubeconfig file (default "~/.kube/config")
--log-verbosity string Log verbosity level (0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace) (default "info")
--loki-endpoint string HTTP endpoint for sending logs to Loki (e.g., http://loki.testnet.internal/loki/api/v1/push)
--tracing-enable Enable tracing for performance monitoring and debugging
--tracing-endpoint string Endpoint for sending tracing data, specified as host:port (default "127.0.0.1:6831")
--tracing-host string Host address for sending tracing data
--tracing-port string Port for sending tracing data
--tracing-service-name string Service name identifier used in tracing data (default "beekeeper")
```

## Public Testnet Checks
Expand Down
33 changes: 19 additions & 14 deletions cmd/beekeeper/cmd/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,43 @@ import (
"github.com/spf13/cobra"
)

func (c *command) initCheckCmd() (err error) {
var errMissingClusterName = fmt.Errorf("cluster name not provided")

func (c *command) initCheckCmd() error {
const (
optionNameClusterName = "cluster-name"
optionNameCreateCluster = "create-cluster"
optionNameChecks = "checks"
optionNameMetricsEnabled = "metrics-enabled"
optionNameSeed = "seed"
optionNameTimeout = "timeout"
optionNameMetricsPusherAddress = "metrics-pusher-address"
// TODO: optionNameStages = "stages"
)

cmd := &cobra.Command{
Use: "check",
Short: "runs integration tests on a Bee cluster",
Long: `runs integration tests on a Bee cluster.`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithTimeout(cmd.Context(), c.globalConfig.GetDuration(optionNameTimeout))
defer cancel()

checks := c.globalConfig.GetStringSlice(optionNameChecks)
if len(checks) == 0 {
return fmt.Errorf("no checks provided")
}

clusterName := c.globalConfig.GetString(optionNameClusterName)
if clusterName == "" {
return errMissingClusterName
}

// set cluster config
cfgCluster, ok := c.config.Clusters[c.globalConfig.GetString(optionNameClusterName)]
cfgCluster, ok := c.config.Clusters[clusterName]
if !ok {
return fmt.Errorf("cluster %s not defined", c.globalConfig.GetString(optionNameClusterName))
return fmt.Errorf("cluster %s not defined", clusterName)
}

// setup cluster
cluster, err := c.setupCluster(ctx,
c.globalConfig.GetString(optionNameClusterName),
c.config,
c.globalConfig.GetBool(optionNameCreateCluster),
)
cluster, err := c.setupCluster(ctx, clusterName, c.globalConfig.GetBool(optionNameCreateCluster))
if err != nil {
return fmt.Errorf("cluster setup: %w", err)
}
Expand Down Expand Up @@ -88,7 +93,7 @@ func (c *command) initCheckCmd() (err error) {
}

// run checks
for _, checkName := range c.globalConfig.GetStringSlice(optionNameChecks) {
for _, checkName := range checks {
checkName = strings.TrimSpace(checkName)
// get configuration
checkConfig, ok := c.config.Checks[checkName]
Expand Down Expand Up @@ -147,7 +152,7 @@ func (c *command) initCheckCmd() (err error) {
PreRunE: c.preRunE,
}

cmd.Flags().String(optionNameClusterName, "default", "cluster name")
cmd.Flags().String(optionNameClusterName, "", "cluster name. Required")
cmd.Flags().String(optionNameMetricsPusherAddress, "pushgateway.staging.internal", "prometheus metrics pusher address")
cmd.Flags().Bool(optionNameCreateCluster, false, "creates cluster before executing checks")
cmd.Flags().StringSlice(optionNameChecks, []string{"pingpong"}, "list of checks to execute")
Expand Down
Loading
Loading