forked from cerc-io/plugeth
swarm/dev: add development environment (#14332)
This PR adds a Swarm development environment which can be run in a Docker container and provides scripts for building binaries and running Swarm clusters.
This commit is contained in:
parent
727eadacca
commit
0036e2a747
2
swarm/dev/.dockerignore
Normal file
2
swarm/dev/.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
bin/*
|
||||||
|
cluster/*
|
2
swarm/dev/.gitignore
vendored
Normal file
2
swarm/dev/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
bin/*
|
||||||
|
cluster/*
|
42
swarm/dev/Dockerfile
Normal file
42
swarm/dev/Dockerfile
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
FROM ubuntu:xenial
|
||||||
|
|
||||||
|
# install build + test dependencies
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install --yes --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
fuse \
|
||||||
|
g++ \
|
||||||
|
gcc \
|
||||||
|
git \
|
||||||
|
iproute2 \
|
||||||
|
iputils-ping \
|
||||||
|
less \
|
||||||
|
libc6-dev \
|
||||||
|
make \
|
||||||
|
pkg-config \
|
||||||
|
&& \
|
||||||
|
apt-get clean
|
||||||
|
|
||||||
|
# install Go
|
||||||
|
ENV GO_VERSION 1.8.1
|
||||||
|
RUN curl -fSLo golang.tar.gz "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" && \
|
||||||
|
tar -xzf golang.tar.gz -C /usr/local && \
|
||||||
|
rm golang.tar.gz
|
||||||
|
ENV GOPATH /go
|
||||||
|
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
|
||||||
|
|
||||||
|
# install docker CLI
|
||||||
|
RUN curl -fSLo docker.tar.gz https://get.docker.com/builds/Linux/x86_64/docker-17.04.0-ce.tgz && \
|
||||||
|
tar -xzf docker.tar.gz -C /usr/local/bin --strip-components=1 docker/docker && \
|
||||||
|
rm docker.tar.gz
|
||||||
|
|
||||||
|
# install jq
|
||||||
|
RUN curl -fSLo /usr/local/bin/jq https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && \
|
||||||
|
chmod +x /usr/local/bin/jq
|
||||||
|
|
||||||
|
# install govendor
|
||||||
|
RUN go get -u github.com/kardianos/govendor
|
||||||
|
|
||||||
|
# add custom bashrc
|
||||||
|
ADD bashrc /root/.bashrc
|
14
swarm/dev/Makefile
Normal file
14
swarm/dev/Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.PHONY: build cluster test
|
||||||
|
|
||||||
|
default: build
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -o bin/swarm github.com/ethereum/go-ethereum/cmd/swarm
|
||||||
|
go build -o bin/geth github.com/ethereum/go-ethereum/cmd/geth
|
||||||
|
go build -o bin/bootnode github.com/ethereum/go-ethereum/cmd/bootnode
|
||||||
|
|
||||||
|
cluster: build
|
||||||
|
scripts/boot-cluster.sh
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test -v github.com/ethereum/go-ethereum/swarm/...
|
20
swarm/dev/README.md
Normal file
20
swarm/dev/README.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Swarm development environment
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The Swarm development environment is a Linux bash shell which can be run in a
|
||||||
|
Docker container and provides a predictable build and test environment.
|
||||||
|
|
||||||
|
### Start the Docker container
|
||||||
|
|
||||||
|
Run the `run.sh` script to build the Docker image and run it, you will then be
|
||||||
|
at a bash prompt inside the `swarm/dev` directory.
|
||||||
|
|
||||||
|
### Build binaries
|
||||||
|
|
||||||
|
Run `make` to build the `swarm`, `geth` and `bootnode` binaries into the
|
||||||
|
`swarm/dev/bin` directory.
|
||||||
|
|
||||||
|
### Boot a cluster
|
||||||
|
|
||||||
|
Run `make cluster` to start a 3 node Swarm cluster, or run
|
||||||
|
`scripts/boot-cluster.sh --size N` to boot a cluster of size N.
|
21
swarm/dev/bashrc
Normal file
21
swarm/dev/bashrc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export ROOT="${GOPATH}/src/github.com/ethereum/go-ethereum"
|
||||||
|
export PATH="${ROOT}/swarm/dev/bin:${PATH}"
|
||||||
|
|
||||||
|
cd "${ROOT}/swarm/dev"
|
||||||
|
|
||||||
|
cat <<WELCOME
|
||||||
|
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
Welcome to the swarm development environment.
|
||||||
|
|
||||||
|
- Run 'make' to build the swarm, geth and bootnode binaries
|
||||||
|
- Run 'make test' to run the swarm unit tests
|
||||||
|
- Run 'make cluster' to start a swarm cluster
|
||||||
|
- Run 'exit' to exit the development environment
|
||||||
|
|
||||||
|
See the 'scripts' directory for some useful scripts.
|
||||||
|
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
WELCOME
|
90
swarm/dev/run.sh
Executable file
90
swarm/dev/run.sh
Executable file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# A script to build and run the Swarm development environment using Docker.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
|
|
||||||
|
# DEFAULT_NAME is the default name for the Docker image and container
|
||||||
|
DEFAULT_NAME="swarm-dev"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<USAGE
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Build and run the Swarm development environment.
|
||||||
|
|
||||||
|
Depends on Docker being installed locally.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-n, --name NAME Docker image and container name [default: ${DEFAULT_NAME}]
|
||||||
|
-d, --docker-args ARGS Custom args to pass to 'docker run' (e.g. '-p 8000:8000' to expose a port)
|
||||||
|
-h, --help Show this message
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local name="${DEFAULT_NAME}"
|
||||||
|
local docker_args=""
|
||||||
|
parse_args "$@"
|
||||||
|
build_image
|
||||||
|
run_image
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-n | --name)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
echo "ERROR: --name flag requires an argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
name="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-d | --docker-args)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
echo "ERROR: --docker-args flag requires an argument" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
docker_args="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -ne 0 ]]; then
|
||||||
|
usage
|
||||||
|
echo "ERROR: invalid arguments" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_image() {
|
||||||
|
docker build --tag "${name}" "${ROOT}/swarm/dev"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_image() {
|
||||||
|
exec docker run \
|
||||||
|
--privileged \
|
||||||
|
--interactive \
|
||||||
|
--tty \
|
||||||
|
--rm \
|
||||||
|
--hostname "${name}" \
|
||||||
|
--name "${name}" \
|
||||||
|
--volume "${ROOT}:/go/src/github.com/ethereum/go-ethereum" \
|
||||||
|
--volume "/var/run/docker.sock:/var/run/docker.sock" \
|
||||||
|
${docker_args} \
|
||||||
|
"${name}" \
|
||||||
|
/bin/bash
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
288
swarm/dev/scripts/boot-cluster.sh
Executable file
288
swarm/dev/scripts/boot-cluster.sh
Executable file
@ -0,0 +1,288 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# A script to boot a dev swarm cluster on a Linux host (typically in a Docker
|
||||||
|
# container started with swarm/dev/run.sh).
|
||||||
|
#
|
||||||
|
# The cluster contains a bootnode, a geth node and multiple swarm nodes, with
|
||||||
|
# each node having its own data directory in a base directory passed with the
|
||||||
|
# --dir flag (default is swarm/dev/cluster).
|
||||||
|
#
|
||||||
|
# To avoid using different ports for each node and to make networking more
|
||||||
|
# realistic, each node gets its own network namespace with IPs assigned from
|
||||||
|
# the 192.168.33.0/24 subnet:
|
||||||
|
#
|
||||||
|
# bootnode: 192.168.33.2
|
||||||
|
# geth: 192.168.33.3
|
||||||
|
# swarm: 192.168.33.10{1,2,...,n}
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
source "${ROOT}/swarm/dev/scripts/util.sh"
|
||||||
|
|
||||||
|
# DEFAULT_BASE_DIR is the default base directory to store node data
|
||||||
|
DEFAULT_BASE_DIR="${ROOT}/swarm/dev/cluster"
|
||||||
|
|
||||||
|
# DEFAULT_CLUSTER_SIZE is the default swarm cluster size
|
||||||
|
DEFAULT_CLUSTER_SIZE=3
|
||||||
|
|
||||||
|
# Linux bridge configuration for connecting the node network namespaces
|
||||||
|
BRIDGE_NAME="swarmbr0"
|
||||||
|
BRIDGE_IP="192.168.33.1"
|
||||||
|
|
||||||
|
# static bootnode configuration
|
||||||
|
BOOTNODE_IP="192.168.33.2"
|
||||||
|
BOOTNODE_PORT="30301"
|
||||||
|
BOOTNODE_KEY="32078f313bea771848db70745225c52c00981589ad6b5b49163f0f5ee852617d"
|
||||||
|
BOOTNODE_PUBKEY="760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"
|
||||||
|
BOOTNODE_URL="enode://${BOOTNODE_PUBKEY}@${BOOTNODE_IP}:${BOOTNODE_PORT}"
|
||||||
|
|
||||||
|
# static geth configuration
|
||||||
|
GETH_IP="192.168.33.3"
|
||||||
|
GETH_RPC_PORT="8545"
|
||||||
|
GETH_RPC_URL="http://${GETH_IP}:${GETH_RPC_PORT}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<USAGE
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Boot a dev swarm cluster.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-d, --dir DIR Base directory to store node data [default: ${DEFAULT_BASE_DIR}]
|
||||||
|
-s, --size SIZE Size of swarm cluster [default: ${DEFAULT_CLUSTER_SIZE}]
|
||||||
|
-h, --help Show this message
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local base_dir="${DEFAULT_BASE_DIR}"
|
||||||
|
local cluster_size="${DEFAULT_CLUSTER_SIZE}"
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
local pid_dir="${base_dir}/pids"
|
||||||
|
local log_dir="${base_dir}/logs"
|
||||||
|
mkdir -p "${base_dir}" "${pid_dir}" "${log_dir}"
|
||||||
|
|
||||||
|
stop_cluster
|
||||||
|
create_network
|
||||||
|
start_bootnode
|
||||||
|
start_geth_node
|
||||||
|
start_swarm_nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-d | --dir)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--dir flag requires an argument"
|
||||||
|
fi
|
||||||
|
base_dir="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-s | --size)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--size flag requires an argument"
|
||||||
|
fi
|
||||||
|
cluster_size="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -ne 0 ]]; then
|
||||||
|
usage
|
||||||
|
fail "ERROR: invalid arguments: $@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_cluster() {
|
||||||
|
info "stopping existing cluster"
|
||||||
|
"${ROOT}/swarm/dev/scripts/stop-cluster.sh" --dir "${base_dir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# create_network creates a Linux bridge which is used to connect the node
|
||||||
|
# network namespaces together
|
||||||
|
create_network() {
|
||||||
|
local subnet="${BRIDGE_IP}/24"
|
||||||
|
|
||||||
|
info "creating ${subnet} network on ${BRIDGE_NAME}"
|
||||||
|
ip link add name "${BRIDGE_NAME}" type bridge
|
||||||
|
ip link set dev "${BRIDGE_NAME}" up
|
||||||
|
ip address add "${subnet}" dev "${BRIDGE_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# start_bootnode starts a bootnode which is used to bootstrap the geth and
|
||||||
|
# swarm nodes
|
||||||
|
start_bootnode() {
|
||||||
|
local key_file="${base_dir}/bootnode.key"
|
||||||
|
echo -n "${BOOTNODE_KEY}" > "${key_file}"
|
||||||
|
|
||||||
|
local args=(
|
||||||
|
--addr "${BOOTNODE_IP}:${BOOTNODE_PORT}"
|
||||||
|
--nodekey "${key_file}"
|
||||||
|
--verbosity "6"
|
||||||
|
)
|
||||||
|
|
||||||
|
start_node "bootnode" "${BOOTNODE_IP}" "$(which bootnode)" ${args[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# start_geth_node starts a geth node with --datadir pointing at <base-dir>/geth
|
||||||
|
# and a single, unlocked account with password "geth"
|
||||||
|
start_geth_node() {
|
||||||
|
local dir="${base_dir}/geth"
|
||||||
|
mkdir -p "${dir}"
|
||||||
|
|
||||||
|
local password="geth"
|
||||||
|
echo "${password}" > "${dir}/password"
|
||||||
|
|
||||||
|
# create an account if necessary
|
||||||
|
if [[ ! -e "${dir}/keystore" ]]; then
|
||||||
|
info "creating geth account"
|
||||||
|
create_account "${dir}" "${password}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get the account address
|
||||||
|
local address="$(jq --raw-output '.address' ${dir}/keystore/*)"
|
||||||
|
if [[ -z "${address}" ]]; then
|
||||||
|
fail "failed to get geth account address"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local args=(
|
||||||
|
--datadir "${dir}"
|
||||||
|
--networkid "321"
|
||||||
|
--bootnodes "${BOOTNODE_URL}"
|
||||||
|
--unlock "${address}"
|
||||||
|
--password "${dir}/password"
|
||||||
|
--rpc
|
||||||
|
--rpcaddr "${GETH_IP}"
|
||||||
|
--rpcport "${GETH_RPC_PORT}"
|
||||||
|
--verbosity "6"
|
||||||
|
)
|
||||||
|
|
||||||
|
start_node "geth" "${GETH_IP}" "$(which geth)" ${args[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
start_swarm_nodes() {
|
||||||
|
for i in $(seq 1 ${cluster_size}); do
|
||||||
|
start_swarm_node "${i}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# start_swarm_node starts a swarm node with a name like "swarmNN" (where NN is
|
||||||
|
# a zero-padded integer like "07"), --datadir pointing at <base-dir>/<name>
|
||||||
|
# (e.g. <base-dir>/swarm07) and a single account with <name> as the password
|
||||||
|
start_swarm_node() {
|
||||||
|
local num=$1
|
||||||
|
local name="swarm$(printf '%02d' ${num})"
|
||||||
|
local ip="192.168.33.1$(printf '%02d' ${num})"
|
||||||
|
|
||||||
|
local dir="${base_dir}/${name}"
|
||||||
|
mkdir -p "${dir}"
|
||||||
|
|
||||||
|
local password="${name}"
|
||||||
|
echo "${password}" > "${dir}/password"
|
||||||
|
|
||||||
|
# create an account if necessary
|
||||||
|
if [[ ! -e "${dir}/keystore" ]]; then
|
||||||
|
info "creating account for ${name}"
|
||||||
|
create_account "${dir}" "${password}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get the account address
|
||||||
|
local address="$(jq --raw-output '.address' ${dir}/keystore/*)"
|
||||||
|
if [[ -z "${address}" ]]; then
|
||||||
|
fail "failed to get swarm account address"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local args=(
|
||||||
|
--bootnodes "${BOOTNODE_URL}"
|
||||||
|
--datadir "${dir}"
|
||||||
|
--identity "${name}"
|
||||||
|
--ethapi "${GETH_RPC_URL}"
|
||||||
|
--bzznetworkid "321"
|
||||||
|
--bzzaccount "${address}"
|
||||||
|
--password "${dir}/password"
|
||||||
|
--verbosity "6"
|
||||||
|
)
|
||||||
|
|
||||||
|
start_node "${name}" "${ip}" "$(which swarm)" ${args[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# start_node runs the node command as a daemon in a network namespace
|
||||||
|
start_node() {
|
||||||
|
local name="$1"
|
||||||
|
local ip="$2"
|
||||||
|
local path="$3"
|
||||||
|
local cmd_args=${@:4}
|
||||||
|
|
||||||
|
info "starting ${name} with IP ${ip}"
|
||||||
|
|
||||||
|
create_node_network "${name}" "${ip}"
|
||||||
|
|
||||||
|
# add a marker to the log file
|
||||||
|
cat >> "${log_dir}/${name}.log" <<EOF
|
||||||
|
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
Starting ${name} node - $(date)
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# run the command in the network namespace using start-stop-daemon to
|
||||||
|
# daemonise the process, sending all output to the log file
|
||||||
|
local daemon_args=(
|
||||||
|
--start
|
||||||
|
--background
|
||||||
|
--no-close
|
||||||
|
--make-pidfile
|
||||||
|
--pidfile "${pid_dir}/${name}.pid"
|
||||||
|
--exec "${path}"
|
||||||
|
)
|
||||||
|
if ! ip netns exec "${name}" start-stop-daemon ${daemon_args[@]} -- $cmd_args &>> "${log_dir}/${name}.log"; then
|
||||||
|
fail "could not start ${name}, check ${log_dir}/${name}.log"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# create_node_network creates a network namespace and connects it to the Linux
|
||||||
|
# bridge using a veth pair
|
||||||
|
create_node_network() {
|
||||||
|
local name="$1"
|
||||||
|
local ip="$2"
|
||||||
|
|
||||||
|
# create the namespace
|
||||||
|
ip netns add "${name}"
|
||||||
|
|
||||||
|
# create the veth pair
|
||||||
|
local veth0="veth${name}0"
|
||||||
|
local veth1="veth${name}1"
|
||||||
|
ip link add name "${veth0}" type veth peer name "${veth1}"
|
||||||
|
|
||||||
|
# add one end to the bridge
|
||||||
|
ip link set dev "${veth0}" master "${BRIDGE_NAME}"
|
||||||
|
ip link set dev "${veth0}" up
|
||||||
|
|
||||||
|
# add the other end to the namespace, rename it eth0 and give it the ip
|
||||||
|
ip link set dev "${veth1}" netns "${name}"
|
||||||
|
ip netns exec "${name}" ip link set dev "${veth1}" name "eth0"
|
||||||
|
ip netns exec "${name}" ip link set dev "eth0" up
|
||||||
|
ip netns exec "${name}" ip address add "${ip}/24" dev "eth0"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_account() {
|
||||||
|
local dir=$1
|
||||||
|
local password=$2
|
||||||
|
|
||||||
|
geth --datadir "${dir}" --password /dev/stdin account new <<< "${password}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
96
swarm/dev/scripts/random-uploads.sh
Executable file
96
swarm/dev/scripts/random-uploads.sh
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# A script to upload random data to a swarm cluster.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# random-uploads.sh --addr 192.168.33.101:8500 --size 40k --count 1000
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
source "${ROOT}/swarm/dev/scripts/util.sh"
|
||||||
|
|
||||||
|
DEFAULT_ADDR="localhost:8500"
|
||||||
|
DEFAULT_UPLOAD_SIZE="40k"
|
||||||
|
DEFAULT_UPLOAD_COUNT="1000"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<USAGE
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Upload random data to a Swarm cluster.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-a, --addr ADDR Swarm API address [default: ${DEFAULT_ADDR}]
|
||||||
|
-s, --size SIZE Individual upload size [default: ${DEFAULT_UPLOAD_SIZE}]
|
||||||
|
-c, --count COUNT Number of uploads [default: ${DEFAULT_UPLOAD_COUNT}]
|
||||||
|
-h, --help Show this message
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local addr="${DEFAULT_ADDR}"
|
||||||
|
local upload_size="${DEFAULT_UPLOAD_SIZE}"
|
||||||
|
local upload_count="${DEFAULT_UPLOAD_COUNT}"
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
info "uploading ${upload_count} ${upload_size} random files to ${addr}"
|
||||||
|
|
||||||
|
for i in $(seq 1 ${upload_count}); do
|
||||||
|
info "upload ${i} / ${upload_count}:"
|
||||||
|
do_random_upload
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
do_random_upload() {
|
||||||
|
curl -fsSL -X POST --data-binary "$(random_data)" "http://${addr}/bzzr:/"
|
||||||
|
}
|
||||||
|
|
||||||
|
random_data() {
|
||||||
|
dd if=/dev/urandom of=/dev/stdout bs="${upload_size}" count=1 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-a | --addr)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--addr flag requires an argument"
|
||||||
|
fi
|
||||||
|
addr="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-s | --size)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--size flag requires an argument"
|
||||||
|
fi
|
||||||
|
upload_size="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-c | --count)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--count flag requires an argument"
|
||||||
|
fi
|
||||||
|
upload_count="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -ne 0 ]]; then
|
||||||
|
usage
|
||||||
|
fail "ERROR: invalid arguments: $@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
98
swarm/dev/scripts/stop-cluster.sh
Executable file
98
swarm/dev/scripts/stop-cluster.sh
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# A script to shutdown a dev swarm cluster.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||||
|
source "${ROOT}/swarm/dev/scripts/util.sh"
|
||||||
|
|
||||||
|
DEFAULT_BASE_DIR="${ROOT}/swarm/dev/cluster"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<USAGE
|
||||||
|
usage: $0 [options]
|
||||||
|
|
||||||
|
Shutdown a dev swarm cluster.
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
-d, --dir DIR Base directory [default: ${DEFAULT_BASE_DIR}]
|
||||||
|
-h, --help Show this message
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local base_dir="${DEFAULT_BASE_DIR}"
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
local pid_dir="${base_dir}/pids"
|
||||||
|
|
||||||
|
stop_swarm_nodes
|
||||||
|
stop_node "geth"
|
||||||
|
stop_node "bootnode"
|
||||||
|
delete_network
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-d | --dir)
|
||||||
|
if [[ -z "$2" ]]; then
|
||||||
|
fail "--dir flag requires an argument"
|
||||||
|
fi
|
||||||
|
base_dir="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $# -ne 0 ]]; then
|
||||||
|
usage
|
||||||
|
fail "ERROR: invalid arguments: $@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_swarm_nodes() {
|
||||||
|
for name in $(ls "${pid_dir}" | grep -oP 'swarm\d+'); do
|
||||||
|
stop_node "${name}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_node() {
|
||||||
|
local name=$1
|
||||||
|
local pid_file="${pid_dir}/${name}.pid"
|
||||||
|
|
||||||
|
if [[ -e "${pid_file}" ]]; then
|
||||||
|
info "stopping ${name}"
|
||||||
|
start-stop-daemon \
|
||||||
|
--stop \
|
||||||
|
--pidfile "${pid_file}" \
|
||||||
|
--remove-pidfile \
|
||||||
|
--oknodo \
|
||||||
|
--retry 15
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ip netns list | grep -qF "${name}"; then
|
||||||
|
ip netns delete "${name}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ip link show "veth${name}0" &>/dev/null; then
|
||||||
|
ip link delete dev "veth${name}0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_network() {
|
||||||
|
if ip link show "swarmbr0" &>/dev/null; then
|
||||||
|
ip link delete dev "swarmbr0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
53
swarm/dev/scripts/util.sh
Normal file
53
swarm/dev/scripts/util.sh
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# shared shell functions
|
||||||
|
|
||||||
|
info() {
|
||||||
|
local msg="$@"
|
||||||
|
local timestamp="$(date +%H:%M:%S)"
|
||||||
|
say "===> ${timestamp} ${msg}" "green"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
local msg="$@"
|
||||||
|
local timestamp=$(date +%H:%M:%S)
|
||||||
|
say "===> ${timestamp} WARN: ${msg}" "yellow" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
local msg="$@"
|
||||||
|
say "ERROR: ${msg}" "red" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# say prints the given message to STDOUT, using the optional color if
|
||||||
|
# STDOUT is a terminal.
|
||||||
|
#
|
||||||
|
# usage:
|
||||||
|
#
|
||||||
|
# say "foo" - prints "foo"
|
||||||
|
# say "bar" "red" - prints "bar" in red
|
||||||
|
# say "baz" "green" - prints "baz" in green
|
||||||
|
# say "qux" "red" | tee - prints "qux" with no colour
|
||||||
|
#
|
||||||
|
say() {
|
||||||
|
local msg=$1
|
||||||
|
local color=$2
|
||||||
|
|
||||||
|
if [[ -n "${color}" ]] && [[ -t 1 ]]; then
|
||||||
|
case "${color}" in
|
||||||
|
red)
|
||||||
|
echo -e "\033[1;31m${msg}\033[0m"
|
||||||
|
;;
|
||||||
|
green)
|
||||||
|
echo -e "\033[1;32m${msg}\033[0m"
|
||||||
|
;;
|
||||||
|
yellow)
|
||||||
|
echo -e "\033[1;33m${msg}\033[0m"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "${msg}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
echo "${msg}"
|
||||||
|
fi
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user