Upstreaming patches written for Garage's benchmark #1

Merged
trinity-1686a merged 7 commits from quentin/mknet:improvements into main 2021-12-13 13:09:28 +00:00
5 changed files with 125 additions and 11 deletions

43
README.md Normal file
View file

@ -0,0 +1,43 @@
# mknet
## Installation
```bash
sudo pip3 install git+https://git.deuxfleurs.fr/trinity-1686a/mknet
```
## Usage
```bash
sudo rm -rf /tmp/garage-testnet/ # always start by deleting previous run
sudo mknet create ./config.yml
sudo mknet run-all example/deploy_garage.sh
sudo mknet run dc1:dc1s1 garage -c /tmp/garage-testnet/dc1/dc1s1/garage.toml status
sudo mknet destroy
```
## Instrumented daemons
If you want to use the scripts provided in the `example` folder,
you must add to your path some tools.
### Garage (`deploy_garage.sh`)
```bash
# see versions on https://garagehq.deuxfleurs.fr/_releases.html
export GRG_ARCH=x86_64-unknown-linux-musl
export GRG_VERSION=v0.5.0
sudo wget https://garagehq.deuxfleurs.fr/_releases/${GRG_VERSION}/${GRG_ARCH}/garage -O /usr/local/bin/garage
sudo chmod +x /usr/local/bin/garage
garage help
```
### Minio (`deploy_minio.py`)
```
sudo wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
sudo chmod +x /usr/local/bin/minio
```

View file

@ -46,15 +46,15 @@ EOF
RUST_LOG=garage=debug ${GARAGE_PATH} server 2>> ${NODE_STORAGE_PATH}/logs & disown RUST_LOG=garage=debug ${GARAGE_PATH} server 2>> ${NODE_STORAGE_PATH}/logs & disown
sleep 2 sleep 2
CONFIG_NODE_FPATH=(${STORAGE_PATH}/*{,/*}/garage.toml) CONFIG_NODE_FPATH=$(find /tmp/garage-testnet/ -maxdepth 3 -name garage.toml|head -n 1)
SELF_ID=$(${GARAGE_PATH} node id 2>/dev/null) SELF_ID=$(${GARAGE_PATH} node id 2>/dev/null)
SHORT_ID=$(echo ${SELF_ID} | cut -c-64) SHORT_ID=$(echo ${SELF_ID} | cut -c-64)
${GARAGE_PATH} -c ${CONFIG_NODE_FPATH[0]} node connect ${SELF_ID} ${GARAGE_PATH} -c ${CONFIG_NODE_FPATH} node connect ${SELF_ID}
${GARAGE_PATH} -c ${CONFIG_NODE_FPATH[0]} layout assign ${SHORT_ID} -z ${ZONE:-unzonned-${HOST}} -c 1 -t ${HOST} ${GARAGE_PATH} -c ${CONFIG_NODE_FPATH} layout assign ${SHORT_ID} -z ${ZONE:-unzonned-${HOST}} -c 1 -t ${HOST}
if [ ${CONFIG_NODE_FPATH[0]} == ${GARAGE_CONFIG_FILE} ]; then if [ ${CONFIG_NODE_FPATH} == ${GARAGE_CONFIG_FILE} ]; then
sleep 2 sleep 2
${GARAGE_PATH} layout show ${GARAGE_PATH} layout show
${GARAGE_PATH} layout apply --version 1 ${GARAGE_PATH} layout apply --version 1

62
example/deploy_minio.py Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env python3
import json, os, sys, time, pathlib, socket, shutil
STORAGE_PATH = os.path.join(os.getcwd(), '.minio-testnet')
HOSTS_PATH = os.path.join(STORAGE_PATH, 'hosts.txt')
UNIX_SOCK = os.path.join(STORAGE_PATH, 'deploy.sock')
DATA_PATH = lambda nid: os.path.join(STORAGE_PATH, 'data'+str(nid))
def main():
if int(os.environ['ID']) == 1: leader()
else: follower()
def leader():
shutil.rmtree(STORAGE_PATH, ignore_errors=True)
os.makedirs(STORAGE_PATH)
print(STORAGE_PATH)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(UNIX_SOCK)
sock.listen()
n_serv = int(os.environ['SERVER_COUNT'])
fl = [ co for co, addr in [ sock.accept() for i in range(n_serv - 1) ]]
identities = [ json.loads(co.makefile().readline()) for co in fl ] + [ { "ip": os.environ['IP'], "path": make_data() } ]
print(f"ident: {identities}")
msg = f"{json.dumps(identities)}\n".encode()
[ co.send(msg) for co in fl ]
run_minio(identities)
def follower():
co = None
while True:
time.sleep(1)
try:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(UNIX_SOCK)
co = sock.makefile()
break
except Exception as err:
print('conn failed, wait,', err)
my_identity = json.dumps({ "ip": os.environ['IP'], "path": make_data() })
sock.send(f"{my_identity}\n".encode())
identities = json.loads(co.readline())
run_minio(identities)
def make_data():
data_path = DATA_PATH(os.environ['ID'])
os.makedirs(data_path)
return data_path
def run_minio(identities):
cmd = f"minio server --console-address ':9001' --address ':9000'"
for ident in identities:
cmd += f" http://[{ident['ip']}]:9000{ident['path']}"
cmd += f" > {os.path.join(STORAGE_PATH, 'minio'+os.environ['ID']+'.log')} 2>&1"
print("launch: ", cmd)
os.system(cmd)
__name__ == '__main__' and main()

View file

@ -1,4 +1,4 @@
#!/bin/env python #!/usr/bin/env python
import ipaddress import ipaddress
import os import os
import shutil import shutil
@ -305,7 +305,7 @@ def run(netns, cmd):
if len(cmd) == 0: if len(cmd) == 0:
cmd = [os.getenv("SHELL") or "/bin/sh"] cmd = [os.getenv("SHELL") or "/bin/sh"]
os.execve("/bin/env", ["/bin/env", "ip", "netns" , "exec", name ] + cmd, env) os.execve("/usr/bin/env", ["/usr/bin/env", "ip", "netns" , "exec", name ] + cmd, env)
def runall(cmd): def runall(cmd):
with open(".current_state.yml", "r") as file: with open(".current_state.yml", "r") as file:
@ -321,6 +321,7 @@ def runall(cmd):
env["HOST"] = server.name env["HOST"] = server.name
env["IP"] = str(server.ip) env["IP"] = str(server.ip)
env["ID"] = str(number) env["ID"] = str(number)
env["SERVER_COUNT"] = str(len(config['servers']))
name = f'testnet-{zone.name}-{server.name}' name = f'testnet-{zone.name}-{server.name}'
net.ns.run(name, cmd, env) net.ns.run(name, cmd, env)
number +=1 number +=1
@ -330,6 +331,7 @@ def runall(cmd):
env["HOST"] = zone.name env["HOST"] = zone.name
env["IP"] = str(zone.ip) env["IP"] = str(zone.ip)
env["ID"] = str(number) env["ID"] = str(number)
env["SERVER_COUNT"] = str(len(config['servers']))
name = f'testnet-{zone.name}-{zone.name}' name = f'testnet-{zone.name}-{zone.name}'
net.ns.run(name, cmd, env) net.ns.run(name, cmd, env)
first = False first = False
@ -343,11 +345,12 @@ def destroy():
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: if len(sys.argv) < 2:
print("""Usage: progname = os.path.basename(sys.argv[0]) if len(sys.argv) > 0 else "mknet"
mk-testnet create [config_path] # create a new network. config_path defailt to config.yml print(f"""Usage:
mk-testnet run-all <cmd> [args...] # run a command as each host. set the IP, NAME and ZONE environment variables {progname} create [config_path] # create a new network. config_path defailt to config.yml
mk-testnet run <name> [cmd [args...]] # run command in host named <name>. Use zonename:name if multiple zones hosts server with same name. If cmd is empty, run a shell {progname} run-all <cmd> [args...] # run a command as each host. set the IP, NAME and ZONE environment variables
mk-testnet destroy # destroy the current environment""") {progname} run <name> [cmd [args...]] # run command in host named <name>. Use zonename:name if multiple zones hosts server with same name. If cmd is empty, run a shell
{progname} destroy # destroy the current environment""")
exit() exit()
cmd = sys.argv[1] cmd = sys.argv[1]
if cmd == "create": if cmd == "create":

6
setup.py Normal file
View file

@ -0,0 +1,6 @@
from distutils.core import setup
setup(name='mknet',
version='1.0',
scripts=['mknet'],
py_modules=['net'],
)