commit
f431a1c870
@ -1 +0,0 @@ |
||||
for file in $(ls *leader*); do echo $file; cat $file | grep TPS | head -n 2 | cut -f2 -d ":" | cut -f1 -d "," | awk '{ sum += $1; n++ } END { if (n > 0) print sum / n; }'; done |
@ -1,35 +0,0 @@ |
||||
import argparse |
||||
import os |
||||
import random |
||||
import sys |
||||
|
||||
from utils import utils |
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser(description='This script helps you to collect public ips') |
||||
parser.add_argument('--instance_output', type=str, dest='instance_output', |
||||
default='instance_output.txt', |
||||
help='the file contains node_name_tag and region number of created instances.') |
||||
parser.add_argument('--region_config', type=str, |
||||
dest='region_config', default='configuration.txt') |
||||
parser.add_argument('--file_output', type=str, |
||||
dest='file_output', default='raw_ip.txt') |
||||
args = parser.parse_args() |
||||
|
||||
if not args.instance_output or not os.path.isfile(args.instance_output): |
||||
print "%s or %s are not existed" % (args.file_output, args.instance_output) |
||||
sys.exit(1) |
||||
if args.instance_output: |
||||
with open(args.instance_output, "r") as fin, open(args.file_output, "w") as fout: |
||||
total_ips = [] |
||||
node_name_tag_list = [] |
||||
for line in fin.readlines(): |
||||
items = line.split(" ") |
||||
region_number = items[1].strip() |
||||
node_name_tag = items[0].strip() |
||||
ip_list = utils.collect_public_ips(region_number, node_name_tag, args.region_config) |
||||
total_ips.extend([(ip, node_name_tag) for ip in ip_list]) |
||||
random.shuffle(total_ips) |
||||
for tuple in total_ips: |
||||
fout.write(tuple[0] + " " + tuple[1] + "\n") |
||||
print "Done collecting public ips %s" % args.file_output |
@ -1,62 +0,0 @@ |
||||
import argparse |
||||
import logging |
||||
import os |
||||
import stat |
||||
import sys |
||||
|
||||
from utils import utils |
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(threadName)s %(asctime)s - %(name)s - %(levelname)s - %(message)s') |
||||
LOGGER = logging.getLogger(__file__) |
||||
LOGGER.setLevel(logging.INFO) |
||||
|
||||
PEMS = [ |
||||
"virginia-key-benchmark.pem", |
||||
"ohio-key-benchmark.pem", |
||||
"california-key-benchmark.pem", |
||||
"oregon-key-benchmark.pem", |
||||
"tokyo-key-benchmark.pem", |
||||
"singapore-key-benchmark.pem", |
||||
"frankfurt-key-benchmark.pem", |
||||
"ireland-key-benchmark.pem", |
||||
] |
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser(description='This script helps you to genereate distribution config') |
||||
parser.add_argument('--distribution_config', type=str, |
||||
dest='distribution_config', default='distribution_config.txt') |
||||
parser.add_argument('--commander_logging', type=str, |
||||
dest='commander_logging', default='commander_logging.sh') |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
if not os.path.exists(args.distribution_config): |
||||
sys.exit(1) |
||||
with open(args.distribution_config, "r") as fin: |
||||
lines = fin.readlines() |
||||
|
||||
commander_address = None |
||||
commander_region = None |
||||
commander_output = None |
||||
with open(args.distribution_config, "w") as fout: |
||||
for line in lines: |
||||
if "commander" in line: |
||||
items = [item.strip() for item in line.split(" ")] |
||||
commander_address = items[0] |
||||
commander_region = int(items[4][0]) |
||||
commander_output = "\n".join(items) |
||||
else: |
||||
fout.write(line.strip() + "\n") |
||||
LOGGER.info("Generated %s" % args.distribution_config) |
||||
|
||||
if not commander_address or not commander_region: |
||||
LOGGER.info("Failed to extract commander address and commander region.") |
||||
sys.exit(1) |
||||
|
||||
with open(args.commander_logging, "w") as fout: |
||||
fout.write("ssh -i ./keys/%s ec2-user@%s\n" % (PEMS[commander_region - 1], commander_address)) |
||||
st = os.stat(args.commander_logging) |
||||
os.chmod(args.commander_logging, st.st_mode | stat.S_IEXEC) |
||||
LOGGER.info("Generated %s" % args.commander_logging) |
||||
LOGGER.info("DONE.") |
||||
|
@ -1,11 +0,0 @@ |
||||
#!/bin/bash -x |
||||
REGION=$(curl 169.254.169.254/latest/meta-data/placement/availability-zone/ | sed 's/[a-z]$//') |
||||
#yum update -y #This breaking codedeploy right now |
||||
yum install ruby wget -y |
||||
cd /home/ec2-user |
||||
touch yum-not-updated.txt |
||||
wget https://aws-codedeploy-$REGION.s3.amazonaws.com/latest/install |
||||
chmod +x ./install |
||||
./install auto |
||||
mkdir projects |
||||
mkdir projects/src |
@ -1,20 +0,0 @@ |
||||
#!/bin/bash |
||||
cd /home/ec2-user |
||||
commanderIP= # <- Put the commander IP here. |
||||
curl http://$commanderIP:8080/soldier -o soldier |
||||
chmod +x ./soldier |
||||
curl http://$commanderIP:8080/benchmark -o benchmark |
||||
chmod +x ./benchmark |
||||
curl http://$commanderIP:8080/txgen -o txgen |
||||
chmod +x ./txgen |
||||
|
||||
# Get My IP |
||||
ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4` |
||||
|
||||
node_port=9000 |
||||
soldier_port=1$node_port |
||||
# Kill existing soldier |
||||
fuser -k -n tcp $soldier_port |
||||
|
||||
# Run soldier |
||||
./soldier -ip $ip -port $node_port > soldier_log 2>&1 & |
@ -1,8 +0,0 @@ |
||||
1,us-east-1,virginia-key-benchmark,virginia-security-group,virginia,ami-97785bed,sg-04d0b62ee08ce8800 |
||||
2,us-east-2,ohio-key-benchmark,ohio-security-group,ohio,ami-f63b1193,sg-0789078f1c76defbe |
||||
3,us-west-1,california-key-benchmark,california-security-group,california,ami-824c4ee2,sg-0a66ccb6ab9161a14 |
||||
4,us-west-2,oregon-key-benchmark,oregon-security-group,oregon,ami-f2d3638a,sg-020cb5729fa212d43 |
||||
5,ap-northeast-1,tokyo-key-benchmark,tokyo-security-group,tokyo,ami-ceafcba8,sg-009aeb97f675c1ad5 |
||||
6,ap-southeast-1,singapore-key-benchmark,singapore-security-group,singapore,ami-68097514,sg-05f9b60044a19dfb2 |
||||
7,eu-central-1,frankfurt-key-benchmark,frankfurt-security-group,frankfurt,ami-5652ce39,sg-0bb06fcd8b25b5910 |
||||
8,eu-west-1,ireland-key-benchmark,ireland-security-group,ireland,ami-d834aba1,sg-0aa8954acb79fdb58 |
@ -1,8 +0,0 @@ |
||||
1,us-east-1,virginia-key-benchmark,virginia-security-group,virginia,ami-b70554c8,sg-04d0b62ee08ce8800 |
||||
2,us-east-2,ohio-key-benchmark,ohio-security-group,ohio,ami-8c122be9,sg-0789078f1c76defbe |
||||
3,us-west-1,california-key-benchmark,california-security-group,california,ami-e0ba5c83,sg-0a66ccb6ab9161a14 |
||||
4,us-west-2,oregon-key-benchmark,oregon-security-group,oregon,ami-a9d09ed1,sg-020cb5729fa212d43 |
||||
5,ap-northeast-1,tokyo-key-benchmark,tokyo-security-group,tokyo,ami-e99f4896,sg-009aeb97f675c1ad5 |
||||
6,ap-southeast-1,singapore-key-benchmark,singapore-security-group,singapore,ami-05868579,sg-05f9b60044a19dfb2 |
||||
7,eu-central-1,frankfurt-key-benchmark,frankfurt-security-group,frankfurt,ami-7c4f7097,sg-0bb06fcd8b25b5910 |
||||
8,eu-west-1,ireland-key-benchmark,ireland-security-group,ireland,ami-466768ac,sg-0aa8954acb79fdb58 |
@ -1,28 +0,0 @@ |
||||
if [ $# -lt 3 ]; then |
||||
echo "Please provide # of instances, # of shards, # of clients" |
||||
exit 1 |
||||
fi |
||||
|
||||
INSTANCE_NUM=$1 |
||||
SHARD_NUM=$2 |
||||
CLIENT_NUM=$3 |
||||
SLEEP_TIME=10 |
||||
|
||||
echo "Creating $INSTANCE_NUM instances at 8 regions" |
||||
python create_solider_instances.py --regions 1,2,3,4,5,6,7,8 --instances $INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM,$INSTANCE_NUM |
||||
|
||||
|
||||
echo "Sleep for $SLEEP_TIME seconds" |
||||
sleep $SLEEP_TIME |
||||
|
||||
echo "Rung collecting raw ips" |
||||
python collect_public_ips.py --instance_output instance_output.txt |
||||
|
||||
# sleep 10 |
||||
echo "Generate distribution_config" |
||||
python generate_distribution_config.py --ip_list_file raw_ip.txt --shard_number $SHARD_NUM --client_number $CLIENT_NUM |
||||
|
||||
echo "Run commander prepare" |
||||
python commander_prepare.py |
||||
|
||||
aws s3 cp distribution_config.txt s3://unique-bucket-bin/distribution_config.txt --acl public-read-write |
@ -1,193 +0,0 @@ |
||||
import argparse |
||||
import base64 |
||||
import boto3 |
||||
import datetime |
||||
import json |
||||
import sys |
||||
import threading |
||||
import time |
||||
import enum |
||||
|
||||
#TODO REMOVE UTILS |
||||
from utils import utils, spot_fleet, logger |
||||
|
||||
LOGGER = logger.getLogger(__file__) |
||||
REGION_NAME = 'region_name' |
||||
REGION_KEY = 'region_key' |
||||
REGION_SECURITY_GROUP = 'region_security_group' |
||||
REGION_SECURITY_GROUP_ID = 'region_security_group_id' |
||||
REGION_HUMAN_NAME = 'region_human_name' |
||||
INSTANCE_TYPE = 't2.micro' |
||||
REGION_AMI = 'region_ami' |
||||
|
||||
class InstanceResource(enum.Enum): |
||||
ON_DEMAND = 'ondemand' |
||||
SPOT_INSTANCE = 'spot' |
||||
SPOT_FLEET = 'fleet' |
||||
|
||||
def __str__(self): |
||||
return self.value |
||||
|
||||
def run_one_region_on_demand_instances(config, region_number, number_of_instances, tag): |
||||
ec2_client = utils.create_client(config, region_number) |
||||
node_name_tag = create_instances( |
||||
config, ec2_client, region_number, number_of_instances, tag) |
||||
LOGGER.info("Created %s in region %s" % (node_name_tag, region_number)) |
||||
return node_name_tag, ec2_client |
||||
|
||||
def create_instances(config, ec2_client, region_number, number_of_instances, tag): |
||||
node_name_tag = utils.get_node_name_tag2(region_number, tag) |
||||
LOGGER.info("Creating node_name_tag: %s" % node_name_tag) |
||||
available_zone = utils.get_one_availability_zone(ec2_client) |
||||
LOGGER.info("Looking at zone %s to create instances." % available_zone) |
||||
|
||||
time.sleep(2) |
||||
ec2_client.run_instances( |
||||
MinCount=number_of_instances, |
||||
MaxCount=number_of_instances, |
||||
ImageId=config[region_number][utils.REGION_AMI], |
||||
Placement={ |
||||
'AvailabilityZone': available_zone, |
||||
}, |
||||
SecurityGroups=[config[region_number][utils.REGION_SECURITY_GROUP]], |
||||
IamInstanceProfile={ |
||||
'Name': utils.IAM_INSTANCE_PROFILE |
||||
}, |
||||
KeyName=config[region_number][utils.REGION_KEY], |
||||
UserData=utils.USER_DATA, |
||||
InstanceType=utils.INSTANCE_TYPE, |
||||
TagSpecifications=[ |
||||
{ |
||||
'ResourceType': 'instance', |
||||
'Tags': [ |
||||
{ |
||||
'Key': 'Name', |
||||
'Value': node_name_tag |
||||
}, |
||||
] |
||||
}, |
||||
], |
||||
) |
||||
|
||||
retry_count = 10 |
||||
while retry_count > 0: |
||||
try: |
||||
time.sleep(20) |
||||
instance_ids = utils.get_instance_ids2(ec2_client, node_name_tag) |
||||
LOGGER.info("Waiting for all %d instances in region %s with node_name_tag %s to be in RUNNING" % ( |
||||
len(instance_ids), region_number, node_name_tag)) |
||||
break |
||||
except: |
||||
retry_count -= 1 |
||||
LOGGER.info("Failed to get instance ids. Retry again.") |
||||
retry_count = 10 |
||||
while retry_count > 0: |
||||
try: |
||||
time.sleep(20) |
||||
waiter = ec2_client.get_waiter('instance_running') |
||||
waiter.wait(InstanceIds=instance_ids) |
||||
break |
||||
except: |
||||
retry_count -= 1 |
||||
LOGGER.info("Failed to wait.") |
||||
|
||||
retry_count = 10 |
||||
while retry_count > 0: |
||||
time.sleep(20) |
||||
LOGGER.info("Waiting ...") |
||||
ip_list = utils.collect_public_ips_from_ec2_client( |
||||
ec2_client, node_name_tag) |
||||
if len(ip_list) == number_of_instances: |
||||
LOGGER.info("Created %d instances" % number_of_instances) |
||||
return node_name_tag |
||||
retry_count -= 10 |
||||
LOGGER.info("Can not get %d instances" % number_of_instances) |
||||
return node_name_tag |
||||
|
||||
|
||||
LOCK_FOR_RUN_ONE_REGION = threading.Lock() |
||||
|
||||
def run_for_one_region_on_demand(config, region_number, number_of_instances, fout, fout2): |
||||
tag = 0 |
||||
number_of_instances = int(number_of_instances) |
||||
while number_of_instances > 0: |
||||
number_of_creation = min(utils.MAX_INSTANCES_FOR_DEPLOYMENT, number_of_instances) |
||||
node_name_tag, ec2_client = run_one_region_on_demand_instances( |
||||
config, region_number, number_of_creation, tag) |
||||
if node_name_tag: |
||||
LOGGER.info("Managed to create instances for region %s with name_name_tag %s" % |
||||
(region_number, node_name_tag)) |
||||
instance_ids = utils.get_instance_ids2(ec2_client, node_name_tag) |
||||
LOCK_FOR_RUN_ONE_REGION.acquire() |
||||
try: |
||||
fout.write("%s %s\n" % (node_name_tag, region_number)) |
||||
for instance_id in instance_ids: |
||||
fout2.write(instance_id + " " + node_name_tag + " " + region_number + |
||||
" " + config[region_number][utils.REGION_NAME] + "\n") |
||||
finally: |
||||
LOCK_FOR_RUN_ONE_REGION.release() |
||||
else: |
||||
LOGGER.info("Failed to create instances for region %s" % region_number) |
||||
number_of_instances -= number_of_creation |
||||
tag += 1 |
||||
|
||||
def read_region_config(region_config='configuration.txt'): |
||||
global CONFIG |
||||
config = {} |
||||
with open(region_config, 'r') as f: |
||||
for myline in f: |
||||
mylist = [item.strip() for item in myline.strip().split(',')] |
||||
region_num = mylist[0] |
||||
config[region_num] = {} |
||||
config[region_num][REGION_NAME] = mylist[1] |
||||
config[region_num][REGION_KEY] = mylist[2] |
||||
config[region_num][REGION_SECURITY_GROUP] = mylist[3] |
||||
config[region_num][REGION_HUMAN_NAME] = mylist[4] |
||||
config[region_num][REGION_AMI] = mylist[5] |
||||
config[region_num][REGION_SECURITY_GROUP_ID] = mylist[6] |
||||
CONFIG = config |
||||
return config |
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser( |
||||
description='This script helps you start instances across multiple regions') |
||||
parser.add_argument('--regions', type=str, dest='regions', |
||||
default='3', help="Supply a csv list of all regions") |
||||
parser.add_argument('--instances', type=str, dest='num_instance_list', |
||||
default='1', help='number of instances in respective of region') |
||||
parser.add_argument('--region_config', type=str, |
||||
dest='region_config', default='configuration.txt') |
||||
parser.add_argument('--instance_output', type=str, dest='instance_output', |
||||
default='instance_output.txt', help='the file to append or write') |
||||
parser.add_argument('--instance_ids_output', type=str, dest='instance_ids_output', |
||||
default='instance_ids_output.txt', help='the file to append or write') |
||||
parser.add_argument('--instance_resource', dest='instance_resource', type=InstanceResource, |
||||
default=InstanceResource.ON_DEMAND, choices=list(InstanceResource)) |
||||
parser.add_argument('--append', dest='append', type=bool, default=False, |
||||
help='append to the current instance_output') |
||||
args = parser.parse_args() |
||||
config = read_region_config(args.region_config) |
||||
region_list = args.regions.split(',') |
||||
num_instance_list = args.num_instance_list.split(',') |
||||
instance_resource = args.instance_resource |
||||
assert len(region_list) == len(num_instance_list), "number of regions: %d != number of instances per region: %d" % ( |
||||
len(region_list), len(num_instance_list)) |
||||
|
||||
write_mode = "a" if args.append else "w" |
||||
with open(args.instance_output, write_mode) as fout, open(args.instance_ids_output, write_mode) as fout2: |
||||
thread_pool = [] |
||||
for i in range(len(region_list)): |
||||
region_number = region_list[i] |
||||
number_of_instances = num_instance_list[i] |
||||
if instance_resource == InstanceResource.ON_DEMAND: |
||||
t = threading.Thread(target=run_for_one_region_on_demand, args=( |
||||
config, region_number, number_of_instances, fout, fout2)) |
||||
elif instance_resource == InstanceResource.SPOT_FLEET: |
||||
t = threading.Thread(target=spot_fleet.run_one_region, args=( |
||||
region_number, number_of_instances, fout, fout2)) |
||||
LOGGER.info("creating thread for region %s" % region_number) |
||||
t.start() |
||||
thread_pool.append(t) |
||||
for t in thread_pool: |
||||
t.join() |
||||
LOGGER.info("done.") |
@ -1,8 +0,0 @@ |
||||
# Change the commander address |
||||
if [ $# -eq 0 ]; then |
||||
echo "Please provide ip address of the commander" |
||||
exit 1 |
||||
fi |
||||
ADDRESS=$1 |
||||
mkdir -p ./tmp |
||||
scp -r -i "california-key-benchmark.pem" ec2-user@$ADDRESS:~/projects/src/harmony-benchmark/bin/upload ./tmp/ |
@ -1,17 +0,0 @@ |
||||
# Make sure to have all keys with mode 600 at harmony-benchmark directory. |
||||
IFS=$'\n' |
||||
rm -rf ./tmp |
||||
mkdir tmp |
||||
for address in $(cat ./leader_addresses.txt) |
||||
do |
||||
echo "trying to download from address $address" |
||||
mkdir -p tmp/$address |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/california-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/frankfurt-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/ireland-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/ohio-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/oregon-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/singapore-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/tokyo-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
scp -r -o "StrictHostKeyChecking no" -i ../keys/virginia-key-benchmark.pem ec2-user@$address:/home/tmp_log/* ./tmp/$address/ |
||||
done |
@ -1,233 +0,0 @@ |
||||
/* |
||||
Commander has two modes to setup configuration: Local and S3. |
||||
|
||||
Local Config Mode |
||||
|
||||
The Default Mode. |
||||
|
||||
Add `-mode local` or omit `-mode` to enter local config mode. In this mode, the `commander` will host the config file `config.txt` on the commander machine and `solider`s will download the config file from `http://{commander_ip}:{commander_port}/distribution_config.txt`. |
||||
|
||||
Remote Config Mode |
||||
|
||||
Add `-mode remote` to enter remote config mode. In this mode, the `soldier`s will download the config file from a remote URL (use `-config_url {url}` to set the URL). |
||||
*/ |
||||
package main |
||||
|
||||
import ( |
||||
"bufio" |
||||
"flag" |
||||
"fmt" |
||||
"io" |
||||
"log" |
||||
"net" |
||||
"net/http" |
||||
"os" |
||||
"strings" |
||||
"time" |
||||
|
||||
"github.com/simple-rules/harmony-benchmark/aws-experiment-launch/experiment/utils" |
||||
"github.com/simple-rules/harmony-benchmark/configr" |
||||
) |
||||
|
||||
type commanderSetting struct { |
||||
ip string |
||||
port string |
||||
mode string |
||||
// Options in s3 mode
|
||||
configURL string |
||||
|
||||
configr *configr.Configr |
||||
} |
||||
|
||||
type sessionInfo struct { |
||||
id string |
||||
uploadFolder string |
||||
} |
||||
|
||||
var ( |
||||
setting commanderSetting |
||||
session sessionInfo |
||||
) |
||||
|
||||
const ( |
||||
DistributionFileName = "distribution_config.txt" |
||||
DefaultConfigUrl = "https://s3-us-west-2.amazonaws.com/unique-bucket-bin/distribution_config.txt" |
||||
) |
||||
|
||||
func handleCommand(command string) { |
||||
args := strings.Split(command, " ") |
||||
if len(args) <= 0 { |
||||
return |
||||
} |
||||
|
||||
switch cmd := args[0]; cmd { |
||||
case "config": |
||||
if setting.mode == "s3" { |
||||
// In s3 mode, download the config file from configURL first.
|
||||
if err := utils.DownloadFile(DistributionFileName, setting.configURL); err != nil { |
||||
panic(err) |
||||
} |
||||
} |
||||
|
||||
err := setting.configr.ReadConfigFile(DistributionFileName) |
||||
if err == nil { |
||||
log.Printf("The loaded config has %v nodes\n", len(setting.configr.GetConfigEntries())) |
||||
} else { |
||||
log.Println("Failed to read config file") |
||||
} |
||||
case "init": |
||||
session.id = time.Now().Format("150405-20060102") |
||||
// create upload folder
|
||||
session.uploadFolder = fmt.Sprintf("upload/%s", session.id) |
||||
err := os.MkdirAll(session.uploadFolder, os.ModePerm) |
||||
if err != nil { |
||||
log.Println("Failed to create upload folder", session.uploadFolder) |
||||
return |
||||
} |
||||
log.Println("New session", session.id) |
||||
|
||||
dictateNodes(fmt.Sprintf("init %v %v %v %v", setting.ip, setting.port, setting.configURL, session.id)) |
||||
case "ping", "kill", "log", "log2": |
||||
dictateNodes(command) |
||||
default: |
||||
log.Println("Unknown command") |
||||
} |
||||
} |
||||
|
||||
func config(ip string, port string, mode string, configURL string) { |
||||
setting.ip = ip |
||||
setting.port = port |
||||
setting.mode = mode |
||||
if mode == "local" { |
||||
setting.configURL = fmt.Sprintf("http://%s:%s/%s", ip, port, DistributionFileName) |
||||
} else { |
||||
setting.configURL = configURL |
||||
} |
||||
setting.configr = configr.NewConfigr() |
||||
} |
||||
|
||||
func dictateNodes(command string) { |
||||
resultChan := make(chan int) |
||||
configs := setting.configr.GetConfigEntries() |
||||
for _, entry := range configs { |
||||
port := "1" + entry.Port // the port number of solider is "1" + node port
|
||||
addr := strings.Join([]string{entry.IP, port}, ":") |
||||
|
||||
go func(resultChan chan int) { |
||||
resultChan <- dictateNode(addr, command) |
||||
}(resultChan) |
||||
} |
||||
count := len(configs) |
||||
res := 0 |
||||
for ; count > 0; count-- { |
||||
res += <-resultChan |
||||
} |
||||
|
||||
log.Printf("Finished %s with %v nodes\n", command, res) |
||||
} |
||||
|
||||
func dictateNode(addr string, command string) int { |
||||
// creates client
|
||||
conn, err := net.DialTimeout("tcp", addr, 5*time.Second) |
||||
if err != nil { |
||||
log.Println(err) |
||||
return 0 |
||||
} |
||||
defer conn.Close() |
||||
|
||||
// send command
|
||||
_, err = conn.Write([]byte(command)) |
||||
if err != nil { |
||||
log.Printf("Failed to send command to %s", addr) |
||||
return 0 |
||||
} |
||||
// log.Printf("Send \"%s\" to %s", command, addr)
|
||||
|
||||
// read response
|
||||
buff := make([]byte, 1024) |
||||
if n, err := conn.Read(buff); err == nil { |
||||
received := string(buff[:n]) |
||||
// log.Printf("Receive from %s: %s", addr, buff[:n])
|
||||
if strings.Contains(received, "Failed") { |
||||
return 0 |
||||
} else { |
||||
return 1 |
||||
} |
||||
} |
||||
return 0 |
||||
} |
||||
|
||||
func handleUploadRequest(w http.ResponseWriter, r *http.Request) { |
||||
if r.Method != http.MethodPost { |
||||
// reject non-post requests
|
||||
jsonResponse(w, http.StatusBadRequest, "Only post request is accepted.") |
||||
return |
||||
} |
||||
|
||||
reader, err := r.MultipartReader() |
||||
if err != nil { |
||||
jsonResponse(w, http.StatusBadRequest, err.Error()) |
||||
return |
||||
} |
||||
|
||||
for { |
||||
part, err := reader.NextPart() |
||||
if err == io.EOF { |
||||
break |
||||
} |
||||
|
||||
dst, err := os.Create(fmt.Sprintf("%s/%s", session.uploadFolder, part.FileName())) |
||||
log.Println(part.FileName()) |
||||
if err != nil { |
||||
jsonResponse(w, http.StatusInternalServerError, err.Error()) |
||||
return |
||||
} |
||||
defer dst.Close() |
||||
|
||||
if _, err := io.Copy(dst, part); err != nil { |
||||
jsonResponse(w, http.StatusInternalServerError, err.Error()) |
||||
return |
||||
} |
||||
} |
||||
} |
||||
|
||||
func jsonResponse(w http.ResponseWriter, code int, message string) { |
||||
w.Header().Set("Content-Type", "application/json") |
||||
w.WriteHeader(code) |
||||
fmt.Fprint(w, message) |
||||
log.Println(message) |
||||
} |
||||
|
||||
func serve() { |
||||
if setting.mode == "local" { |
||||
// Only host config file if in local mode
|
||||
http.Handle("/", http.FileServer(http.Dir("./"))) |
||||
} |
||||
http.HandleFunc("/upload", handleUploadRequest) |
||||
err := http.ListenAndServe(":"+setting.port, nil) |
||||
if err != nil { |
||||
log.Fatalf("Failed to setup server! Error: %s", err.Error()) |
||||
} |
||||
log.Printf("Start to host upload endpoint at http://%s:%s/upload\n", setting.ip, setting.port) |
||||
} |
||||
|
||||
func main() { |
||||
ip := flag.String("ip", "127.0.0.1", "The ip of commander, i.e. this machine") |
||||
port := flag.String("port", "8080", "The port which the commander uses to communicate with soldiers") |
||||
mode := flag.String("mode", "local", "The config mode, local or s3") |
||||
configURL := flag.String("config_url", DefaultConfigUrl, "The config URL") |
||||
flag.Parse() |
||||
|
||||
config(*ip, *port, *mode, *configURL) |
||||
|
||||
go serve() |
||||
|
||||
scanner := bufio.NewScanner(os.Stdin) |
||||
for true { |
||||
log.Printf("Listening to Your Command:") |
||||
if !scanner.Scan() { |
||||
break |
||||
} |
||||
handleCommand(scanner.Text()) |
||||
} |
||||
} |
@ -1,312 +0,0 @@ |
||||
/* |
||||
Soldier is responsible for receiving commands from commander and doing tasks such as starting nodes, uploading logs. |
||||
|
||||
cd harmony-benchmark/bin |
||||
go build -o soldier ../aws-experiment-launch/experiment/soldier/main.go |
||||
./soldier -ip={node_ip} -port={node_port} |
||||
*/ |
||||
package main |
||||
|
||||
import ( |
||||
"bufio" |
||||
"bytes" |
||||
"flag" |
||||
"fmt" |
||||
"io" |
||||
"io/ioutil" |
||||
"log" |
||||
"mime/multipart" |
||||
"net" |
||||
"net/http" |
||||
"os" |
||||
"path/filepath" |
||||
"runtime" |
||||
"strings" |
||||
|
||||
"github.com/simple-rules/harmony-benchmark/aws-experiment-launch/experiment/soldier/s3" |
||||
"github.com/simple-rules/harmony-benchmark/aws-experiment-launch/experiment/utils" |
||||
"github.com/simple-rules/harmony-benchmark/configr" |
||||
globalUtils "github.com/simple-rules/harmony-benchmark/utils" |
||||
) |
||||
|
||||
type soliderSetting struct { |
||||
ip string |
||||
port string |
||||
} |
||||
|
||||
type sessionInfo struct { |
||||
id string |
||||
commanderIP string |
||||
commanderPort string |
||||
localConfigFileName string |
||||
logFolder string |
||||
configr *configr.Configr |
||||
myConfig configr.ConfigEntry |
||||
} |
||||
|
||||
const ( |
||||
bucketName = "richard-bucket-test" |
||||
logFolderPrefix = "../tmp_log/" |
||||
) |
||||
|
||||
var ( |
||||
setting soliderSetting |
||||
globalSession sessionInfo |
||||
) |
||||
|
||||
func socketServer() { |
||||
soldierPort := "1" + setting.port // the soldier port is "1" + node port
|
||||
listen, err := net.Listen("tcp4", ":"+soldierPort) |
||||
if err != nil { |
||||
log.Fatalf("Socket listen port %s failed,%s", soldierPort, err) |
||||
os.Exit(1) |
||||
} |
||||
defer listen.Close() |
||||
log.Printf("Begin listen for command on port: %s", soldierPort) |
||||
|
||||
for { |
||||
conn, err := listen.Accept() |
||||
if err != nil { |
||||
log.Fatalln(err) |
||||
continue |
||||
} |
||||
go handler(conn) |
||||
} |
||||
} |
||||
|
||||
func handler(conn net.Conn) { |
||||
defer conn.Close() |
||||
|
||||
var ( |
||||
buf = make([]byte, 1024) |
||||
r = bufio.NewReader(conn) |
||||
w = bufio.NewWriter(conn) |
||||
) |
||||
|
||||
ILOOP: |
||||
for { |
||||
n, err := r.Read(buf) |
||||
data := string(buf[:n]) |
||||
|
||||
switch err { |
||||
case io.EOF: |
||||
break ILOOP |
||||
case nil: |
||||
log.Println("Received command", data) |
||||
|
||||
handleCommand(data, w) |
||||
|
||||
log.Println("Waiting for new command...") |
||||
|
||||
default: |
||||
log.Fatalf("Receive data failed:%s", err) |
||||
return |
||||
} |
||||
} |
||||
} |
||||
|
||||
func handleCommand(command string, w *bufio.Writer) { |
||||
args := strings.Split(command, " ") |
||||
|
||||
if len(args) <= 0 { |
||||
return |
||||
} |
||||
|
||||
switch command := args[0]; command { |
||||
case "ping": |
||||
{ |
||||
handlePingCommand(w) |
||||
} |
||||
case "init": |
||||
{ |
||||
handleInitCommand(args[1:], w) |
||||
} |
||||
case "kill": |
||||
{ |
||||
handleKillCommand(w) |
||||
} |
||||
case "log": |
||||
{ |
||||
handleLogCommand(w) |
||||
} |
||||
case "log2": |
||||
{ |
||||
handleLog2Command(w) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func handleInitCommand(args []string, w *bufio.Writer) { |
||||
// init ip port config_file sessionID
|
||||
log.Println("Init command", args) |
||||
|
||||
// read arguments
|
||||
ip := args[0] |
||||
globalSession.commanderIP = ip |
||||
port := args[1] |
||||
globalSession.commanderPort = port |
||||
configURL := args[2] |
||||
sessionID := args[3] |
||||
globalSession.id = sessionID |
||||
globalSession.logFolder = fmt.Sprintf("%slog-%v", logFolderPrefix, sessionID) |
||||
|
||||
// create local config file
|
||||
globalSession.localConfigFileName = fmt.Sprintf("node_config_%v_%v.txt", setting.port, globalSession.id) |
||||
utils.DownloadFile(globalSession.localConfigFileName, configURL) |
||||
log.Println("Successfully downloaded config") |
||||
|
||||
globalSession.configr.ReadConfigFile(globalSession.localConfigFileName) |
||||
globalSession.myConfig = *globalSession.configr.GetMyConfigEntry(setting.ip, setting.port) |
||||
|
||||
if err := runInstance(); err == nil { |
||||
logAndReply(w, "Done init.") |
||||
} else { |
||||
logAndReply(w, "Failed.") |
||||
} |
||||
} |
||||
|
||||
func handleKillCommand(w *bufio.Writer) { |
||||
log.Println("Kill command") |
||||
if err := killPort(setting.port); err == nil { |
||||
logAndReply(w, "Done kill.") |
||||
} else { |
||||
logAndReply(w, "Failed.") |
||||
} |
||||
} |
||||
|
||||
func killPort(port string) error { |
||||
if runtime.GOOS == "windows" { |
||||
command := fmt.Sprintf("(Get-NetTCPConnection -LocalPort %s).OwningProcess -Force", port) |
||||
return globalUtils.RunCmd("Stop-Process", "-Id", command) |
||||
} else { |
||||
command := fmt.Sprintf("lsof -i tcp:%s | grep LISTEN | awk '{print $2}' | xargs kill -9", port) |
||||
return globalUtils.RunCmd("bash", "-c", command) |
||||
} |
||||
} |
||||
|
||||
func handlePingCommand(w *bufio.Writer) { |
||||
log.Println("Ping command") |
||||
logAndReply(w, "I'm alive") |
||||
} |
||||
|
||||
func handleLogCommand(w *bufio.Writer) { |
||||
log.Println("Log command") |
||||
|
||||
files, err := ioutil.ReadDir(globalSession.logFolder) |
||||
if err != nil { |
||||
logAndReply(w, fmt.Sprintf("Failed to read log folder. Error: %s", err.Error())) |
||||
return |
||||
} |
||||
|
||||
filePaths := make([]string, len(files)) |
||||
for i, f := range files { |
||||
filePaths[i] = fmt.Sprintf("%s/%s", globalSession.logFolder, f.Name()) |
||||
} |
||||
|
||||
req, err := newUploadFileRequest( |
||||
fmt.Sprintf("http://%s:%s/upload", globalSession.commanderIP, globalSession.commanderPort), |
||||
"file", |
||||
filePaths, |
||||
nil) |
||||
if err != nil { |
||||
logAndReply(w, fmt.Sprintf("Failed to create upload request. Error: %s", err.Error())) |
||||
return |
||||
} |
||||
client := &http.Client{} |
||||
_, err = client.Do(req) |
||||
if err != nil { |
||||
logAndReply(w, fmt.Sprintf("Failed to upload log. Error: %s", err.Error())) |
||||
return |
||||
} |
||||
logAndReply(w, "Upload log done!") |
||||
} |
||||
|
||||
// Creates a new file upload http request with optional extra params
|
||||
func newUploadFileRequest(uri string, paramName string, paths []string, params map[string]string) (*http.Request, error) { |
||||
body := &bytes.Buffer{} |
||||
writer := multipart.NewWriter(body) |
||||
for _, path := range paths { |
||||
file, err := os.Open(path) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
defer file.Close() |
||||
part, err := writer.CreateFormFile(paramName, filepath.Base(path)) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
_, err = io.Copy(part, file) |
||||
log.Printf(path) |
||||
} |
||||
|
||||
for key, val := range params { |
||||
_ = writer.WriteField(key, val) |
||||
} |
||||
err := writer.Close() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
req, err := http.NewRequest("POST", uri, body) |
||||
req.Header.Set("Content-Type", writer.FormDataContentType()) |
||||
return req, err |
||||
} |
||||
|
||||
func logAndReply(w *bufio.Writer, message string) { |
||||
log.Println(message) |
||||
w.Write([]byte(message)) |
||||
w.Flush() |
||||
} |
||||
|
||||
func handleLog2Command(w *bufio.Writer) { |
||||
log.Println("Log command") |
||||
|
||||
files, err := ioutil.ReadDir(globalSession.logFolder) |
||||
if err != nil { |
||||
logAndReply(w, fmt.Sprintf("Failed to create log folder. Error: %s", err.Error())) |
||||
return |
||||
} |
||||
|
||||
filePaths := make([]string, len(files)) |
||||
for i, f := range files { |
||||
filePaths[i] = fmt.Sprintf("%s/%s", globalSession.logFolder, f.Name()) |
||||
} |
||||
|
||||
// TODO: currently only upload the first file.
|
||||
_, err = s3.UploadFile(bucketName, filePaths[0], strings.Replace(filePaths[0], logFolderPrefix, "", 1)) |
||||
if err != nil { |
||||
logAndReply(w, fmt.Sprintf("Failed to create upload request. Error: %s", err.Error())) |
||||
return |
||||
} |
||||
logAndReply(w, "Upload log done!") |
||||
} |
||||
|
||||
func runInstance() error { |
||||
os.MkdirAll(globalSession.logFolder, os.ModePerm) |
||||
|
||||
if globalSession.myConfig.Role == "client" { |
||||
return runClient() |
||||
} |
||||
return runNode() |
||||
} |
||||
|
||||
func runNode() error { |
||||
log.Println("running instance") |
||||
return globalUtils.RunCmd("./benchmark", "-ip", setting.ip, "-port", setting.port, "-config_file", globalSession.localConfigFileName, "-log_folder", globalSession.logFolder) |
||||
} |
||||
|
||||
func runClient() error { |
||||
log.Println("running client") |
||||
return globalUtils.RunCmd("./txgen", "-config_file", globalSession.localConfigFileName, "-log_folder", globalSession.logFolder) |
||||
} |
||||
|
||||
func main() { |
||||
ip := flag.String("ip", "127.0.0.1", "IP of the node.") |
||||
port := flag.String("port", "9000", "port of the node.") |
||||
flag.Parse() |
||||
|
||||
setting.ip = *ip |
||||
setting.port = *port |
||||
|
||||
socketServer() |
||||
} |
@ -1,93 +0,0 @@ |
||||
package s3 |
||||
|
||||
import ( |
||||
"fmt" |
||||
"log" |
||||
"os" |
||||
|
||||
"github.com/aws/aws-sdk-go/aws" |
||||
"github.com/aws/aws-sdk-go/aws/awserr" |
||||
"github.com/aws/aws-sdk-go/aws/endpoints" |
||||
"github.com/aws/aws-sdk-go/aws/session" |
||||
"github.com/aws/aws-sdk-go/service/s3" |
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager" |
||||
) |
||||
|
||||
func createSession() *session.Session { |
||||
return session.Must(session.NewSession(&aws.Config{ |
||||
Region: aws.String(endpoints.UsWest2RegionID), |
||||
MaxRetries: aws.Int(3), |
||||
})) |
||||
} |
||||
|
||||
func CreateBucket(bucketName string, region string) { |
||||
sess := createSession() |
||||
svc := s3.New(sess) |
||||
input := &s3.CreateBucketInput{ |
||||
Bucket: aws.String(bucketName), |
||||
CreateBucketConfiguration: &s3.CreateBucketConfiguration{ |
||||
LocationConstraint: aws.String(region), |
||||
}, |
||||
} |
||||
|
||||
result, err := svc.CreateBucket(input) |
||||
if err != nil { |
||||
if aerr, ok := err.(awserr.Error); ok { |
||||
switch aerr.Code() { |
||||
case s3.ErrCodeBucketAlreadyExists: |
||||
fmt.Println(s3.ErrCodeBucketAlreadyExists, aerr.Error()) |
||||
case s3.ErrCodeBucketAlreadyOwnedByYou: |
||||
fmt.Println(s3.ErrCodeBucketAlreadyOwnedByYou, aerr.Error()) |
||||
default: |
||||
fmt.Println(aerr.Error()) |
||||
} |
||||
} else { |
||||
// Print the error, cast err to awserr.Error to get the Code and
|
||||
// Message from an error.
|
||||
fmt.Println(err.Error()) |
||||
} |
||||
return |
||||
} |
||||
|
||||
fmt.Println(result) |
||||
} |
||||
|
||||
func UploadFile(bucketName string, fileName string, key string) (result *s3manager.UploadOutput, err error) { |
||||
sess := createSession() |
||||
uploader := s3manager.NewUploader(sess) |
||||
|
||||
f, err := os.Open(fileName) |
||||
if err != nil { |
||||
log.Println("Failed to open file", err) |
||||
return nil, err |
||||
} |
||||
// Upload the file to S3.
|
||||
result, err = uploader.Upload(&s3manager.UploadInput{ |
||||
Bucket: aws.String(bucketName), |
||||
Key: aws.String(key), |
||||
Body: f, |
||||
}) |
||||
if err != nil { |
||||
log.Println("failed to upload file", err) |
||||
return nil, err |
||||
} |
||||
fmt.Printf("file uploaded to, %s\n", result.Location) |
||||
return result, nil |
||||
} |
||||
|
||||
func DownloadFile(bucketName string, fileName string, key string) (n int64, err error) { |
||||
sess := createSession() |
||||
|
||||
downloader := s3manager.NewDownloader(sess) |
||||
|
||||
f, err := os.Create(fileName) |
||||
if err != nil { |
||||
return |
||||
} |
||||
|
||||
n, err = downloader.Download(f, &s3.GetObjectInput{ |
||||
Bucket: aws.String(bucketName), |
||||
Key: aws.String(key), |
||||
}) |
||||
return |
||||
} |
@ -1,30 +0,0 @@ |
||||
package utils |
||||
|
||||
import ( |
||||
"io" |
||||
"net/http" |
||||
"os" |
||||
) |
||||
|
||||
func DownloadFile(filepath string, url string) error { |
||||
// Create the file
|
||||
out, err := os.Create(filepath) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer out.Close() |
||||
|
||||
// Get the data
|
||||
resp, err := http.Get(url) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer resp.Body.Close() |
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
return nil |
||||
} |
@ -1,37 +0,0 @@ |
||||
import argparse |
||||
import logging |
||||
import sys |
||||
|
||||
from utils import utils |
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(threadName)s %(asctime)s - %(name)s - %(levelname)s - %(message)s') |
||||
LOGGER = logging.getLogger(__file__) |
||||
LOGGER.setLevel(logging.INFO) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser(description='This script helps you to genereate distribution config') |
||||
parser.add_argument('--ip_list_file', type=str, dest='ip_list_file', |
||||
default='raw_ip.txt', help="the file containing available raw ips") |
||||
# If the ip_list_file is None we need to use the region, node_name_tag and region_config to collect raw_ip |
||||
parser.add_argument('--region', type=str, dest='region_number', |
||||
default="4", help="region number") |
||||
parser.add_argument('--node_name_tag', type=str, |
||||
dest='node_name_tag', default='4-NODE-23-36-01-2018-07-05') |
||||
parser.add_argument('--region_config', type=str, |
||||
dest='region_config', default='configuration.txt') |
||||
|
||||
parser.add_argument('--shard_number', type=int, dest='shard_number', default=1) |
||||
parser.add_argument('--client_number', type=int, dest='client_number', default=1) |
||||
parser.add_argument('--distribution_config', type=str, |
||||
dest='distribution_config', default='distribution_config.txt') |
||||
args = parser.parse_args() |
||||
|
||||
if args.ip_list_file == None: |
||||
utils.generate_distribution_config2( |
||||
args.region_number, args.node_name_tag, args.region_config, |
||||
args.shard_number, args.client_number, args.distribution_config) |
||||
else: |
||||
utils.generate_distribution_config3(args.shard_number, args.client_number, |
||||
args.ip_list_file, args.distribution_config) |
||||
LOGGER.info("Done writing %s" % args.distribution_config) |
@ -1 +0,0 @@ |
||||
scp -i ../keys/ohio-key-benchmark.pem ec2-user@18.219.217.193:~/projects/src/harmony-benchmark/bin/upload tmp/ |
@ -1,96 +0,0 @@ |
||||
import json |
||||
import sys |
||||
import os |
||||
import argparse |
||||
|
||||
def formatFloat(v): |
||||
return "%.2f" % v |
||||
|
||||
def formatPercent(v): |
||||
return formatFloat(v) + "%" |
||||
|
||||
def formatMem(v): |
||||
return formatFloat(float(v) / 10**6) + "MB" |
||||
|
||||
class Profiler: |
||||
def __init__(self): |
||||
self.tps = 0 |
||||
self.tps_max = 0 |
||||
self.tps_min = sys.maxsize |
||||
self.tps_count = 0 |
||||
|
||||
self.cpu_percent = 0 |
||||
self.cpu_usr = 0 |
||||
self.cpu_sys = 0 |
||||
self.cpu_count = 0 |
||||
|
||||
self.mem_rss = 0 |
||||
self.mem_rss_max = 0 |
||||
self.mem_count = 0 |
||||
|
||||
def handleTPS(self, obj): |
||||
tps = obj["TPS"] |
||||
self.tps += tps |
||||
self.tps_max = max(self.tps_max, tps) |
||||
self.tps_min = min(self.tps_min, tps) |
||||
self.tps_count += 1 |
||||
|
||||
def handleCPU(self, obj): |
||||
# http://psutil.readthedocs.io/en/latest/#psutil.Process.cpu_times |
||||
# https://stackoverflow.com/questions/556405/what-do-real-user-and-sys-mean-in-the-output-of-time1 |
||||
# http://psutil.readthedocs.io/en/latest/#psutil.Process.cpu_percent |
||||
self.cpu_percent += obj["percent"] |
||||
times = json.loads(obj["times"]) |
||||
self.cpu_usr = times["user"] |
||||
self.cpu_sys = times["system"] |
||||
self.cpu_count += 1 |
||||
|
||||
def handleMem(self, obj): |
||||
# http://psutil.readthedocs.io/en/latest/#psutil.Process.memory_info |
||||
info = json.loads(obj["info"]) |
||||
rss = info["rss"] |
||||
self.mem_rss += rss |
||||
self.mem_rss_max = max(self.mem_rss_max, rss) |
||||
self.mem_count += 1 |
||||
|
||||
def report(self): |
||||
print("TPS", |
||||
"Avg", formatFloat(self.tps / self.tps_count), |
||||
"Min", formatFloat(self.tps_min), |
||||
"Max", formatFloat(self.tps_max)) |
||||
print("CPU", |
||||
"Percent (Avg)", formatPercent(self.cpu_percent / self.cpu_count), |
||||
"Time (Usr)", str(self.cpu_usr) + "s", |
||||
"Time (Sys)", str(self.cpu_sys) + "s") |
||||
print("Mem", |
||||
"RSS (Max)", formatMem(self.mem_rss_max), |
||||
"RSS (Avg)", formatMem(self.mem_rss / self.mem_count)) |
||||
|
||||
def profileFile(path): |
||||
print(path) |
||||
profiler = Profiler() |
||||
with open(path) as f: |
||||
for line in f: |
||||
obj = json.loads(line) |
||||
if obj["lvl"] != "info": |
||||
continue |
||||
if obj["msg"] == "TPS Report": |
||||
profiler.handleTPS(obj) |
||||
elif obj["msg"] == "CPU Report": |
||||
profiler.handleCPU(obj) |
||||
elif obj["msg"] == "Mem Report": |
||||
profiler.handleMem(obj) |
||||
profiler.report() |
||||
|
||||
# Example: python report_extractor.py --folder ../tmp_log/log-20180713-205431 |
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser( |
||||
description="This script extracts reports from log files") |
||||
parser.add_argument("--folder", type=str, dest="folder", |
||||
default="", |
||||
help="the path to the log folder") |
||||
args = parser.parse_args() |
||||
|
||||
for filename in os.listdir(args.folder): |
||||
if "leader" in filename: |
||||
profileFile(os.path.join(args.folder, filename)) |
@ -1,18 +0,0 @@ |
||||
aws ec2 request-spot-instances \ |
||||
--instance-count 1 \ |
||||
--block-duration-minutes 60 \ |
||||
--launch-specification "{ \ |
||||
\"ImageId\": \"ami-f2d3638a\", \ |
||||
\"InstanceType\": \"m3.medium\", \ |
||||
\"SecurityGroups\": [ \ |
||||
\"richard-spot-instance SSH\" \ |
||||
], \ |
||||
\"KeyName\": \"richard-spot-instance\", \ |
||||
\"IamInstanceProfile\": { \ |
||||
\"Name\": \"BenchMarkCodeDeployInstanceProfile\" \ |
||||
}, \ |
||||
\"UserData\": \"`base64 ../configs/userdata-commander.sh`\" \ |
||||
}" \ |
||||
#--dry-run # uncomment this line to send a real request. |
||||
|
||||
# Note: on windows, you need to add `-w 0` to the base64 command" |
@ -1,10 +0,0 @@ |
||||
aws ec2 run-instances \ |
||||
--count 1 \ |
||||
--image-id "ami-f2d3638a" \ |
||||
--instance-type "t2.micro" \ |
||||
--key-name "richard-spot-instance" \ |
||||
--security-groups "richard-spot-instance SSH" \ |
||||
--iam-instance-profile "{ \ |
||||
\"Name\": \"BenchMarkCodeDeployInstanceProfile\" \ |
||||
}" \ |
||||
--user-data "`base64 ../configs/userdata-commander.sh`" |
@ -1,105 +0,0 @@ |
||||
import argparse |
||||
import logging |
||||
import os |
||||
import random |
||||
import sys |
||||
import threading |
||||
import boto3 |
||||
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(threadName)s %(asctime)s - %(name)s - %(levelname)s - %(message)s') |
||||
LOGGER = logging.getLogger(__file__) |
||||
LOGGER.setLevel(logging.INFO) |
||||
|
||||
REGION_NAME = 'region_name' |
||||
REGION_KEY = 'region_key' |
||||
REGION_SECURITY_GROUP = 'region_security_group' |
||||
REGION_SECURITY_GROUP_ID = 'region_security_group_id' |
||||
REGION_HUMAN_NAME = 'region_human_name' |
||||
INSTANCE_TYPE = 't2.micro' |
||||
REGION_AMI = 'region_ami' |
||||
|
||||
def read_configuration_file(filename): |
||||
config = {} |
||||
with open(filename, 'r') as f: |
||||
for myline in f: |
||||
mylist = myline.strip().split(',') |
||||
region_num = mylist[0] |
||||
config[region_num] = {} |
||||
config[region_num][REGION_NAME] = mylist[1] |
||||
config[region_num][REGION_KEY] = mylist[2] |
||||
config[region_num][REGION_SECURITY_GROUP] = mylist[3] |
||||
config[region_num][REGION_HUMAN_NAME] = mylist[4] |
||||
config[region_num][REGION_AMI] = mylist[5] |
||||
config[region_num][REGION_SECURITY_GROUP_ID] = mylist[6] |
||||
return config |
||||
|
||||
def get_instance_ids(describe_instances_response): |
||||
instance_ids = [] |
||||
if describe_instances_response["Reservations"]: |
||||
for reservation in describe_instances_response["Reservations"]: |
||||
instance_ids.extend(instance["InstanceId"] for instance in reservation["Instances"] if instance.get("InstanceId")) |
||||
return instance_ids |
||||
|
||||
def get_instance_ids2(ec2_client, node_name_tag): |
||||
time.sleep(5) |
||||
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}] |
||||
return get_instance_ids(ec2_client.describe_instances(Filters=filters)) |
||||
|
||||
def create_ec2_client(region_number, region_config): |
||||
config = read_configuration_file(region_config) |
||||
region_name = config[region_number][REGION_NAME] |
||||
session = boto3.Session(region_name=region_name) |
||||
return session.client('ec2'), session |
||||
|
||||
def terminate_instances_by_region(region_number, region_config, node_name_tag): |
||||
ec2_client, _ = create_ec2_client(region_number, region_config) |
||||
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}] |
||||
instance_ids = get_instance_ids(ec2_client.describe_instances(Filters=filters)) |
||||
if instance_ids: |
||||
ec2_client.terminate_instances(InstanceIds=instance_ids) |
||||
LOGGER.info("waiting until instances with tag %s died." % node_name_tag) |
||||
waiter = ec2_client.get_waiter('instance_terminated') |
||||
waiter.wait(InstanceIds=instance_ids) |
||||
LOGGER.info("instances with node name tag %s terminated." % node_name_tag) |
||||
else: |
||||
pass |
||||
LOGGER.warn("there is no instances to terminate") |
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser(description='This script helps you to collect public ips') |
||||
parser.add_argument('--instance_output', type=str, dest='instance_output', |
||||
default='instance_output.txt', |
||||
help='the file contains node_name_tag and region number of created instances.') |
||||
parser.add_argument('--node_name_tag', type=str, dest='node_name_tag') |
||||
parser.add_argument('--region_config', type=str, |
||||
dest='region_config', default='configuration.txt') |
||||
args = parser.parse_args() |
||||
|
||||
if args.node_name_tag: |
||||
node_name_tag_items = args.node_name_tag.split(",") |
||||
region_number_items = [item[:1] for item in node_name_tag_items] |
||||
thread_pool = [] |
||||
for i in range(len(region_number_items)): |
||||
region_number = region_number_items[i] |
||||
node_name_tag = node_name_tag_items[i] |
||||
t = threading.Thread(target=terminate_instances_by_region, args=(region_number, args.region_config, node_name_tag)) |
||||
t.start() |
||||
thread_pool.append(t) |
||||
for t in thread_pool: |
||||
t.join() |
||||
LOGGER.info("done.") |
||||
elif args.instance_output: |
||||
with open(args.instance_output, "r") as fin: |
||||
thread_pool = [] |
||||
for line in fin.readlines(): |
||||
items = line.split(" ") |
||||
region_number = items[1].strip() |
||||
node_name_tag = items[0].strip() |
||||
t = threading.Thread(target=terminate_instances_by_region, args=(region_number, args.region_config, node_name_tag)) |
||||
t.start() |
||||
thread_pool.append(t) |
||||
for t in thread_pool: |
||||
t.join() |
||||
LOGGER.info("done.") |
@ -1,15 +0,0 @@ |
||||
import boto3 |
||||
import os |
||||
GOHOME ='/Users/alok/Documents/goworkspace/' |
||||
s3 = boto3.client('s3') |
||||
bucket_name = 'unique-bucket-bin' |
||||
#response = s3.create_bucket(Bucket=bucket_name,ACL='public-read-write', CreateBucketConfiguration={'LocationConstraint': 'us-west-2'}) |
||||
response = s3.list_buckets() |
||||
buckets = [bucket['Name'] for bucket in response['Buckets']] |
||||
print("Bucket List: %s" % buckets) |
||||
dirname = GOHOME + 'src/harmony-benchmark/bin/' |
||||
for myfile in os.listdir(dirname): |
||||
with open('distribution_config.txt','r') as f: |
||||
f = open(os.path.join(dirname,myfile)) |
||||
response = s3.put_object(ACL='public-read-write',Body=f.read(),Bucket=bucket_name,Key=myfile) |
||||
print(response) |
@ -1,10 +0,0 @@ |
||||
import boto3 |
||||
import os |
||||
#from boto3.session import Session |
||||
s3 = boto3.client('s3') |
||||
bucket_name = 'unique-bucket-bin' |
||||
#response = s3.create_bucket(Bucket=bucket_name,ACL='public-read-write', CreateBucketConfiguration={'LocationConstraint': 'us-west-2'}) |
||||
myfile = 'distribution_config.txt' |
||||
with open('distribution_config.txt','r') as f: |
||||
response = s3.put_object(ACL='public-read-write',Body=f.read(),Bucket=bucket_name,Key=myfile) |
||||
print(response) |
@ -1,9 +0,0 @@ |
||||
import boto3 |
||||
s3 = boto3.client('s3') |
||||
bucket_name = 'first-try' |
||||
s3.create_bucket(Bucket=bucket_name,ACL='public-read-write') |
||||
response = s3.list_buckets() |
||||
buckets = [bucket['Name'] for bucket in response['Buckets']] |
||||
print("Bucket List: %s" % buckets) |
||||
filename='myfirst.txt' |
||||
s3.upload_file(filename, bucket_name, filename) |
@ -1,11 +0,0 @@ |
||||
#!/bin/bash -x |
||||
REGION=$(curl 169.254.169.254/latest/meta-data/placement/availability-zone/ | sed 's/[a-z]$//') |
||||
#yum update -y #This breaking codedeploy right now |
||||
yum install ruby wget -y |
||||
cd /home/ec2-user |
||||
touch yum-not-updated.txt |
||||
wget https://aws-codedeploy-$REGION.s3.amazonaws.com/latest/install |
||||
chmod +x ./install |
||||
./install auto |
||||
mkdir projects |
||||
mkdir projects/src |
@ -1,31 +0,0 @@ |
||||
#!/bin/bash |
||||
yum install ruby -y |
||||
cd /home/ec2-user/ |
||||
curl http://unique-bucket-bin.s3.amazonaws.com/txgen -o txgen |
||||
curl http://unique-bucket-bin.s3.amazonaws.com/soldier -o soldier |
||||
curl http://unique-bucket-bin.s3.amazonaws.com/benchmark -o benchmark |
||||
chmod +x ./soldier |
||||
chmod +x ./txgen |
||||
chmod +x ./commander |
||||
chmod +x ./kill_node.sh |
||||
echo "* soft nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* hard nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root soft nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root hard nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root soft nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root hard nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "session required pam_limits.so" | sudo tee -a /etc/pam.d/common-session |
||||
|
||||
# Get My IP |
||||
ip=`curl http://169.254.169.254/latest/meta-data/public-ipv4` |
||||
|
||||
NODE_PORT=9000 |
||||
SOLDIER_PORT=1$NODE_PORT |
||||
# Kill existing soldier/node |
||||
fuser -k -n tcp $SOLDIER_PORT |
||||
fuser -k -n tcp $NODE_PORT |
||||
|
||||
# Run soldier |
||||
./soldier -ip $ip -port $NODE_PORT > soldier_log 2>&1 & |
@ -1,8 +0,0 @@ |
||||
1,us-east-1,virginia-key-benchmark,virginia-security-group,virginia,ami-b70554c8,sg-04d0b62ee08ce8800 |
||||
2,us-east-2,ohio-key-benchmark,ohio-security-group,ohio,ami-8c122be9,sg-0789078f1c76defbe |
||||
3,us-west-1,california-key-benchmark,california-security-group,california,ami-e0ba5c83,sg-0a66ccb6ab9161a14 |
||||
4,us-west-2,oregon-key-benchmark,oregon-security-group,oregon,ami-a9d09ed1,sg-020cb5729fa212d43 |
||||
5,ap-northeast-1,tokyo-key-benchmark,tokyo-security-group,tokyo,ami-e99f4896,sg-009aeb97f675c1ad5 |
||||
6,ap-southeast-1,singapore-key-benchmark,singapore-security-group,singapore,ami-05868579,sg-05f9b60044a19dfb2 |
||||
7,eu-central-1,frankfurt-key-benchmark,frankfurt-security-group,frankfurt,ami-7c4f7097,sg-0bb06fcd8b25b5910 |
||||
8,eu-west-1,ireland-key-benchmark,ireland-security-group,ireland,ami-466768ac,sg-0aa8954acb79fdb58 |
@ -1,46 +0,0 @@ |
||||
|
||||
import utils |
||||
|
||||
|
||||
def get_launch_template_name(region_number): |
||||
return 'benchmark-' + utils.CONFIG[region_number][utils.REGION_NAME] |
||||
|
||||
|
||||
def create(ec2_client, region_number): |
||||
return ec2_client.create_launch_template( |
||||
# DryRun=True, |
||||
LaunchTemplateName=get_launch_template_name(region_number), |
||||
LaunchTemplateData={ |
||||
'IamInstanceProfile': { |
||||
'Name': utils.IAM_INSTANCE_PROFILE |
||||
}, |
||||
'ImageId': utils.CONFIG[region_number][utils.REGION_AMI], |
||||
# 'InstanceType': instance_type, |
||||
'KeyName': utils.CONFIG[region_number][utils.REGION_KEY], |
||||
'UserData': utils.USER_DATA_BASE64, |
||||
'SecurityGroupIds': [ |
||||
utils.CONFIG[region_number][utils.REGION_SECURITY_GROUP_ID] |
||||
], |
||||
# 'InstanceInitiatedShutdownBehavior': 'stop', |
||||
'TagSpecifications': [ |
||||
{ |
||||
'ResourceType': 'instance', |
||||
'Tags': [ |
||||
{ |
||||
'Key': 'LaunchTemplate', |
||||
'Value': 'Yes' |
||||
} |
||||
] |
||||
} |
||||
], |
||||
# 'InstanceMarketOptions': { |
||||
# 'MarketType': 'spot', |
||||
# 'SpotOptions': { |
||||
# 'MaxPrice': 'string', |
||||
# 'SpotInstanceType': 'one-time'|'persistent', |
||||
# 'BlockDurationMinutes': 123, |
||||
# 'InstanceInterruptionBehavior': 'hibernate'|'stop'|'terminate' |
||||
# } |
||||
# }, |
||||
} |
||||
) |
@ -1,9 +0,0 @@ |
||||
import logging |
||||
|
||||
logging.basicConfig(level=logging.INFO, |
||||
format='%(threadName)s %(asctime)s - %(name)s - %(levelname)s - %(message)s') |
||||
|
||||
def getLogger(file): |
||||
LOGGER = logging.getLogger(file) |
||||
LOGGER.setLevel(logging.INFO) |
||||
return LOGGER |
@ -1,119 +0,0 @@ |
||||
import utils |
||||
import logger |
||||
import launch_template |
||||
LOGGER = logger.getLogger(__file__) |
||||
|
||||
|
||||
def create_launch_specification(region_number, instanceType): |
||||
return { |
||||
# Region irrelevant fields |
||||
'IamInstanceProfile': { |
||||
'Name': utils.IAM_INSTANCE_PROFILE |
||||
}, |
||||
'InstanceType': instanceType, |
||||
'UserData': utils.USER_DATA_BASE64, |
||||
# Region relevant fields |
||||
'SecurityGroups': [ |
||||
{ |
||||
# In certain scenarios, we have to use group id instead of group name |
||||
# https://github.com/boto/boto/issues/350#issuecomment-27359492 |
||||
'GroupId': utils.CONFIG[region_number][utils.REGION_SECURITY_GROUP_ID] |
||||
} |
||||
], |
||||
'ImageId': utils.CONFIG[region_number][utils.REGION_AMI], |
||||
'KeyName': utils.CONFIG[region_number][utils.REGION_KEY], |
||||
'TagSpecifications': [ |
||||
{ |
||||
'ResourceType': 'instance', |
||||
'Tags': [ |
||||
{ |
||||
'Key': 'Name', |
||||
'Value': utils.get_node_name_tag(region_number) |
||||
} |
||||
] |
||||
} |
||||
], |
||||
# 'WeightedCapacity': 123.0, |
||||
# 'Placement': { |
||||
# # 'AvailabilityZone': get_one_availability_zone(ec2_client) |
||||
# } |
||||
} |
||||
|
||||
|
||||
def create_launch_specification_list(region_number, instance_type_list): |
||||
return list(map(lambda type: create_launch_specification(region_number, type), instance_type_list)) |
||||
|
||||
|
||||
def get_launch_template(region_number, instance_type): |
||||
return { |
||||
'LaunchTemplateSpecification': { |
||||
'LaunchTemplateName': launch_template.get_launch_template_name(region_number), |
||||
'Version': '1' |
||||
}, |
||||
'Overrides': [ |
||||
{ |
||||
'InstanceType': instance_type |
||||
} |
||||
] |
||||
} |
||||
|
||||
|
||||
def get_launch_template_list(region_number, instance_type_list): |
||||
return list(map(lambda type: get_launch_template(region_number, type), instance_type_list)) |
||||
|
||||
|
||||
def request_spot_fleet(ec2_client, region_number, number_of_instances, instance_type_list): |
||||
LOGGER.info("Requesting spot fleet") |
||||
LOGGER.info("Creating node_name_tag: %s" % |
||||
utils.get_node_name_tag(region_number)) |
||||
# https://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.request_spot_fleet |
||||
response = ec2_client.request_spot_fleet( |
||||
# DryRun=True, |
||||
SpotFleetRequestConfig={ |
||||
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html#spot-fleet-allocation-strategy |
||||
'AllocationStrategy': 'diversified', |
||||
'IamFleetRole': 'arn:aws:iam::656503231766:role/RichardFleetRole', |
||||
'LaunchSpecifications': create_launch_specification_list(region_number, instance_type_list), |
||||
# 'SpotPrice': 'string', # The maximum price per unit hour that you are willing to pay for a Spot Instance. The default is the On-Demand price. |
||||
'TargetCapacity': number_of_instances, |
||||
'Type': 'maintain' |
||||
} |
||||
) |
||||
return response["SpotFleetRequestId"] |
||||
|
||||
|
||||
def request_spot_fleet_with_on_demand(ec2_client, region_number, number_of_instances, number_of_on_demand, instance_type_list): |
||||
LOGGER.info("Requesting spot fleet") |
||||
LOGGER.info("Creating node_name_tag: %s" % |
||||
utils.get_node_name_tag(region_number)) |
||||
# https://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Client.request_spot_fleet |
||||
response = ec2_client.request_spot_fleet( |
||||
# DryRun=True, |
||||
SpotFleetRequestConfig={ |
||||
# https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet.html#spot-fleet-allocation-strategy |
||||
'AllocationStrategy': 'diversified', |
||||
'IamFleetRole': 'arn:aws:iam::656503231766:role/RichardFleetRole', |
||||
'LaunchTemplateConfigs': get_launch_template_list(region_number, instance_type_list), |
||||
# 'SpotPrice': 'string', # The maximum price per unit hour that you are willing to pay for a Spot Instance. The default is the On-Demand price. |
||||
'TargetCapacity': number_of_instances, |
||||
'OnDemandTargetCapacity': number_of_on_demand, |
||||
'Type': 'maintain' |
||||
} |
||||
) |
||||
return response |
||||
|
||||
def get_instance_ids(client, request_id): |
||||
res = client.describe_spot_fleet_instances( |
||||
SpotFleetRequestId=request_id |
||||
) |
||||
return [ inst["InstanceId"] for inst in res["ActiveInstances"] ] |
||||
|
||||
def run_one_region(region_number, number_of_instances, fout, fout2): |
||||
client = utils.create_client(utils.CONFIG, region_number) |
||||
instance_type_list = ['t2.micro', 't2.small', 'm3.medium'] |
||||
# node_name_tag = request_spot_fleet_with_on_demand( |
||||
# client, region_number, int(number_of_instances), 1, instance_type_list) |
||||
request_id = request_spot_fleet( |
||||
client, region_number, int(number_of_instances), instance_type_list) |
||||
instance_ids = get_instance_ids(client, request_id) |
||||
print(instance_ids) # TODO@ricl, no data here since the request is not fulfilled. |
@ -1,210 +0,0 @@ |
||||
import boto3 |
||||
import datetime |
||||
import json |
||||
import sys |
||||
import time |
||||
import base64 |
||||
import threading |
||||
|
||||
|
||||
MAX_INTANCES_FOR_WAITER = 100 |
||||
MAX_INSTANCES_FOR_DEPLOYMENT = 500 |
||||
REGION_NAME = 'region_name' |
||||
REGION_KEY = 'region_key' |
||||
REGION_SECURITY_GROUP = 'region_security_group' |
||||
REGION_SECURITY_GROUP_ID = 'region_security_group_id' |
||||
REGION_HUMAN_NAME = 'region_human_name' |
||||
INSTANCE_TYPE = 't2.micro' |
||||
REGION_AMI = 'region_ami' |
||||
IAM_INSTANCE_PROFILE = 'BenchMarkCodeDeployInstanceProfile' |
||||
time_stamp = time.time() |
||||
CURRENT_SESSION = datetime.datetime.fromtimestamp( |
||||
time_stamp).strftime('%H-%M-%S-%Y-%m-%d') |
||||
NODE_NAME_SUFFIX = "NODE-" + CURRENT_SESSION |
||||
|
||||
def get_node_name_tag(region_number): |
||||
return region_number + "-" + NODE_NAME_SUFFIX |
||||
|
||||
def get_node_name_tag2(region_number, tag): |
||||
return region_number + "-" + NODE_NAME_SUFFIX + "-" + str(tag) |
||||
|
||||
with open("userdata-soldier.sh", "r") as userdata_file: |
||||
USER_DATA = userdata_file.read() |
||||
|
||||
# UserData must be base64 encoded for spot instances. |
||||
USER_DATA_BASE64 = base64.b64encode(USER_DATA) |
||||
|
||||
def create_client(config, region_number): |
||||
region_name = config[region_number][REGION_NAME] |
||||
# Create session. |
||||
session = boto3.Session(region_name=region_name) |
||||
# Create a client. |
||||
return session.client('ec2') |
||||
|
||||
def read_region_config(region_config='configuration.txt'): |
||||
global CONFIG |
||||
config = {} |
||||
with open(region_config, 'r') as f: |
||||
for myline in f: |
||||
mylist = [item.strip() for item in myline.strip().split(',')] |
||||
region_num = mylist[0] |
||||
config[region_num] = {} |
||||
config[region_num][REGION_NAME] = mylist[1] |
||||
config[region_num][REGION_KEY] = mylist[2] |
||||
config[region_num][REGION_SECURITY_GROUP] = mylist[3] |
||||
config[region_num][REGION_HUMAN_NAME] = mylist[4] |
||||
config[region_num][REGION_AMI] = mylist[5] |
||||
config[region_num][REGION_SECURITY_GROUP_ID] = mylist[6] |
||||
CONFIG = config |
||||
return config |
||||
|
||||
def get_ip_list(response): |
||||
if response.get('Instances', None): |
||||
return [instance.get('PublicIpAddress', None) for instance in response['Instances']] |
||||
else: |
||||
return [] |
||||
|
||||
def create_ec2_client(region_number, region_config): |
||||
config = read_region_config(region_config) |
||||
region_name = config[region_number][REGION_NAME] |
||||
session = boto3.Session(region_name=region_name) |
||||
return session.client('ec2'), session |
||||
|
||||
def collect_public_ips_from_ec2_client(ec2_client, node_name_tag): |
||||
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}] |
||||
response = ec2_client.describe_instances(Filters=filters) |
||||
ip_list = [] |
||||
if response.get('Reservations'): |
||||
for reservation in response[u'Reservations']: |
||||
ip_list.extend(instance['PublicIpAddress'] for instance in reservation['Instances'] if instance.get('PublicIpAddress')) |
||||
return ip_list |
||||
|
||||
def collect_public_ips(region_number, node_name_tag, region_config): |
||||
ec2_client, _ = create_ec2_client(region_number, region_config) |
||||
ip_list = collect_public_ips_from_ec2_client(ec2_client, node_name_tag) |
||||
return ip_list |
||||
|
||||
def get_application(codedeploy, application_name): |
||||
response = codedeploy.list_applications() |
||||
if application_name in response['applications']: |
||||
return response |
||||
else: |
||||
response = codedeploy.create_application( |
||||
applicationName=application_name, |
||||
computePlatform='Server' |
||||
) |
||||
return response |
||||
|
||||
def create_deployment_group(codedeploy, region_number,application_name, deployment_group_name, node_name_tag): |
||||
response = codedeploy.list_deployment_groups(applicationName=application_name) |
||||
if response.get('deploymentGroups') and (deployment_group_name in response['deploymentGroups']): |
||||
return None |
||||
else: |
||||
response = codedeploy.create_deployment_group( |
||||
applicationName=application_name, |
||||
deploymentGroupName=deployment_group_name, |
||||
deploymentConfigName='CodeDeployDefault.AllAtOnce', |
||||
serviceRoleArn='arn:aws:iam::656503231766:role/BenchMarkCodeDeployServiceRole', |
||||
deploymentStyle={ |
||||
'deploymentType': 'IN_PLACE', |
||||
'deploymentOption': 'WITHOUT_TRAFFIC_CONTROL' |
||||
}, |
||||
ec2TagFilters = [ |
||||
{ |
||||
'Key': 'Name', |
||||
'Value': node_name_tag, |
||||
'Type': 'KEY_AND_VALUE' |
||||
} |
||||
] |
||||
) |
||||
return response['deploymentGroupId'] |
||||
|
||||
def generate_distribution_config2(region_number, node_name_tag, region_config, |
||||
shard_number, client_number, distribution_config): |
||||
ip_list = collect_public_ips(region_number, node_name_tag, region_config) |
||||
generate_distribution_config(shard_number, client_number, ip_list, distribution_config) |
||||
|
||||
def generate_distribution_config3(shard_number, client_number, ip_list_file, distribution_config): |
||||
with open(ip_list_file, "r") as fin: |
||||
lines = fin.readlines() |
||||
ip_list = [line.strip() for line in lines] |
||||
generate_distribution_config(shard_number, client_number, ip_list, distribution_config) |
||||
|
||||
def generate_distribution_config(shard_number, client_number, ip_list, distribution_config): |
||||
if len(ip_list) < shard_number * 2 + client_number + 1: |
||||
print("Not enough nodes to generate a config file") |
||||
return False |
||||
|
||||
# Create ip for clients. |
||||
commander_id, client_id, leader_id, validator_id = 0, 0, 0, 0 |
||||
validator_number = len(ip_list) - client_number - shard_number - 1 |
||||
with open(distribution_config, "w") as fout: |
||||
for i in range(len(ip_list)): |
||||
ip, node_name_tag = ip_list[i].split(" ") |
||||
if commander_id < 1: |
||||
fout.write("%s 9000 commander %d %s\n" % (ip, commander_id, node_name_tag)) |
||||
commander_id = commander_id + 1 |
||||
elif leader_id < shard_number: |
||||
fout.write("%s 9000 leader %d %s\n" % (ip, leader_id, node_name_tag)) |
||||
leader_id = leader_id + 1 |
||||
elif validator_id < validator_number: |
||||
fout.write("%s 9000 validator %d %s\n" % (ip, validator_id % shard_number, node_name_tag)) |
||||
validator_id = validator_id + 1 |
||||
else: |
||||
fout.write("%s 9000 client %d %s\n" % (ip, client_id % shard_number, node_name_tag)) |
||||
client_id = client_id + 1 |
||||
|
||||
def get_availability_zones(ec2_client): |
||||
response = ec2_client.describe_availability_zones() |
||||
all_zones = [] |
||||
if response.get('AvailabilityZones', None): |
||||
all_zones = [info['ZoneName'] for info in response.get('AvailabilityZones') if info['State'] == 'available'] |
||||
return all_zones |
||||
|
||||
def get_one_availability_zone(ec2_client): |
||||
time.sleep(1) |
||||
all_zones = get_availability_zones(ec2_client) |
||||
if len(all_zones) > 0: |
||||
return all_zones[0] |
||||
else: |
||||
return None |
||||
|
||||
def get_instance_ids2(ec2_client, node_name_tag): |
||||
time.sleep(5) |
||||
filters = [{'Name': 'tag:Name','Values': [node_name_tag]}] |
||||
return get_instance_ids(ec2_client.describe_instances(Filters=filters)) |
||||
|
||||
# Get instance_ids from describe_instances_response. |
||||
def get_instance_ids(describe_instances_response): |
||||
instance_ids = [] |
||||
if describe_instances_response["Reservations"]: |
||||
for reservation in describe_instances_response["Reservations"]: |
||||
instance_ids.extend(instance["InstanceId"] for instance in reservation["Instances"] if instance.get("InstanceId")) |
||||
return instance_ids |
||||
|
||||
WAITER_LOCK = threading.Lock() |
||||
def run_waiter_100_instances_for_status(ec2_client, status, instance_ids): |
||||
time.sleep(10) |
||||
WAITER_LOCK.acquire() |
||||
waiter = ec2_client.get_waiter('instance_running') |
||||
WAITER_LOCK.release() |
||||
waiter.wait(InstanceIds=instance_ids) |
||||
|
||||
def run_waiter_for_status(ec2_client, status, instance_ids): |
||||
thread_pool = [] |
||||
i = 0 |
||||
while i < len(instance_ids): |
||||
j = i + min(len(instance_ids), i + MAX_INTANCES_FOR_WAITER) |
||||
t = threading.Thread(target=run_waiter_100_instances_for_status, args=( |
||||
ec2_client, status, instance_ids[i:j])) |
||||
t.start() |
||||
thread_pool.append(t) |
||||
i = i + MAX_INTANCES_FOR_WAITER |
||||
for t in thread_pool: |
||||
t.join() |
||||
|
||||
# used for testing only. |
||||
# if __name__ == "__main__": |
||||
# ip_list = collect_public_ips('4', "4-NODE-23-36-01-2018-07-05", "configuration.txt") |
||||
# print ip_list |
||||
# generate_distribution_config(2, 1, ip_list, "config_test.txt") |
@ -1,31 +0,0 @@ |
||||
import unittest |
||||
|
||||
from utils import generate_distribution_config |
||||
|
||||
class TestCreateAndDeploy(unittest.TestCase): |
||||
|
||||
def test_generate_config_file(self): |
||||
ips = ["102.000.000.1", "102.000.000.2", "102.000.000.3", "102.000.000.4", "102.000.000.5", "102.000.000.6"] |
||||
generate_distribution_config(2, 2, ips, "config_test.txt") |
||||
with open("config_test.txt", "r") as fin: |
||||
lines = fin.readlines() |
||||
collection = {} |
||||
collection['ip'] = [] |
||||
collection['client'] = {} |
||||
leader_count, validator_count, client_count = 0, 0, 0 |
||||
for line in lines: |
||||
strs = line.split(" ") |
||||
assert(not strs[0] in collection['ip']) |
||||
collection['ip'].append(strs[0]) |
||||
if strs[2] == "client": |
||||
client_count = client_count + 1 |
||||
elif strs[2] == "leader": |
||||
leader_count = leader_count + 1 |
||||
elif strs[2] == "validator": |
||||
validator_count = validator_count + 1 |
||||
assert(validator_count == 2) |
||||
assert(leader_count == 2) |
||||
assert(client_count == 2) |
||||
|
||||
if __name__ == '__main__': |
||||
unittest.main() |
@ -1,5 +0,0 @@ |
||||
for pid in `/bin/ps -fu $USER| grep "slave.go\|slave -port\|leader\|benchmark_node" | grep -v "grep" | awk '{print $2}'`; |
||||
do |
||||
echo 'Killed process: '$pid |
||||
kill -9 $pid |
||||
done |
@ -1,34 +0,0 @@ |
||||
import json |
||||
|
||||
def get_public_ip(all_reservations): |
||||
all_public_ip_addresses = [] |
||||
for individual_instances in all_reservations: |
||||
instance_information = individual_instances['Instances'][0] |
||||
if "running" != instance_information["State"]["Name"]: |
||||
continue |
||||
all_public_ip_addresses.append(instance_information['PublicIpAddress']) |
||||
return all_public_ip_addresses |
||||
|
||||
def make_peers_list(all_reservations,port="9001",filename="config.txt"): |
||||
p = get_public_ip(all_reservations) |
||||
f = open(filename,"w") |
||||
for i in range(len(p)): |
||||
if i == 0: |
||||
f.write(p[i] + " " + port + " " + "leader"+"\n") |
||||
else: |
||||
f.write(p[i] + " " + port + " " + "validator"+"\n") |
||||
f.close() |
||||
|
||||
def is_it_running(f): |
||||
pass |
||||
|
||||
if __name__ == "__main__": |
||||
json_data=open("aws.json").read() |
||||
f = json.loads(json_data) |
||||
all_reservations = f['Reservations'] |
||||
|
||||
make_peers_list(all_reservations) |
||||
|
||||
|
||||
|
||||
|
@ -1,26 +0,0 @@ |
||||
import requests |
||||
amazon_ipv4_url = "http://169.254.169.254/latest/meta-data/public-ipv4" |
||||
def get_my_ip(): |
||||
return current_ip = requests.get(amazon_ipv4_url).text |
||||
|
||||
if __name__ == "__main__": |
||||
current_ip = requests.get(amazon_ipv4_url).text |
||||
f = open("global_nodes.txt","r") |
||||
peerList = [] |
||||
for myline in f: |
||||
mylist = myline.split(" ") |
||||
ip = mylist[0] |
||||
node = mylist[2] |
||||
if str(ip) != str(current_ip): |
||||
if node != "transaction": |
||||
peerList.append(myline) |
||||
else: |
||||
if node == "transaction": |
||||
h = open("isTransaction.txt","w") |
||||
h.write("I am just a transaction generator node") |
||||
h.close() |
||||
f.close() |
||||
g = open("global_peerlist.txt","w") |
||||
for myline in peerList: |
||||
g.write(myline) |
||||
g.close() |
@ -1,34 +0,0 @@ |
||||
#!/bin/bash -x |
||||
echo "Run Instances starts" >> tmplog |
||||
|
||||
echo "Update systcl" >> tmplog |
||||
sudo sysctl net.core.somaxconn=1024 |
||||
sudo sysctl net.core.netdev_max_backlog=65536; |
||||
sudo sysctl net.ipv4.tcp_tw_reuse=1; |
||||
sudo sysctl -w net.ipv4.tcp_rmem='65536 873800 1534217728'; |
||||
sudo sysctl -w net.ipv4.tcp_wmem='65536 873800 1534217728'; |
||||
sudo sysctl -w net.ipv4.tcp_mem='65536 873800 1534217728'; |
||||
|
||||
echo "Setup path" >> tmplog |
||||
./kill_node.sh |
||||
MyHOME=/home/ec2-user |
||||
source ~/.bash_profile |
||||
export GOROOT=/usr/lib/golang |
||||
export GOPATH=$MyHOME/projects |
||||
export PATH=$PATH:$GOROOT/bin |
||||
|
||||
echo "Get ip" >> tmplog |
||||
# Get my IP |
||||
wget http://169.254.169.254/latest/meta-data/public-ipv4 |
||||
ip=$(head -n 1 public-ipv4) |
||||
echo "Current IP is >>>" |
||||
echo $ip |
||||
echo ">>>>" |
||||
|
||||
echo "Run soldier" >> tmplog |
||||
# Run soldier |
||||
cd $GOPATH/src/harmony-benchmark/bin/ |
||||
node_port=9000 |
||||
./soldier -ip $ip -port $node_port > soldier_log 2>&1 & |
||||
|
||||
echo "Run Instances done" >> tmplog |
@ -1 +0,0 @@ |
||||
echo "Bye" >> tmplog |
@ -1 +0,0 @@ |
||||
echo "Hello" >> tmplog |
@ -1,43 +0,0 @@ |
||||
#!/bin/bash -x |
||||
echo "Setup Golang" >> tmplog |
||||
#sudo yum update -y |
||||
|
||||
sudo yum install -y golang |
||||
sudo yum install -y git |
||||
MyHOME=/home/ec2-user |
||||
echo "now setting up go-lang paths" |
||||
# GOROOT is the location where Go package is installed on your system |
||||
echo "export GOROOT=/usr/lib/golang" >> $MyHOME/.bash_profile |
||||
|
||||
# GOPATH is the location of your work directory |
||||
echo "export GOPATH=$MyHOME/projects" >> $MyHOME/.bash_profile |
||||
|
||||
# PATH in order to access go binary system wide |
||||
echo "export PATH=$PATH:$GOROOT/bin" >> $MyHOME/.bash_profile |
||||
|
||||
export GOROOT=/usr/lib/golang |
||||
export GOPATH=$MyHOME/projects |
||||
export PATH=$PATH:$GOROOT/bin |
||||
source $MyHOME/.bash_profile |
||||
|
||||
cd $GOPATH/src/harmony-benchmark |
||||
touch 'yum_not_updated.txt' |
||||
# go get dependencies |
||||
go get ./... |
||||
curl --silent http://169.254.169.254/latest/meta-data/public-ipv4 >> bin/myip.txt |
||||
# build executables |
||||
go build -o bin/soldier aws-experiment-launch/experiment/soldier/main.go |
||||
go build -o bin/commander aws-experiment-launch/experiment/commander/main.go |
||||
go build -o bin/benchmark benchmark.go |
||||
go build -o bin/txgen client/txgen/main.go |
||||
|
||||
# Setup ulimit |
||||
echo "* soft nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* hard nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* soft nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "* hard nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root soft nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root hard nproc 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root soft nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "root hard nofile 65535" | sudo tee -a /etc/security/limits.conf |
||||
echo "session required pam_limits.so" | sudo tee -a /etc/pam.d/common-session |
@ -1 +0,0 @@ |
||||
aws ec2 run-instances --image-id ami-e251209a --count 1 --instance-type t2.nano --key-name main --security-group-ids sg-066a8b0ec187c7247 |
@ -1,177 +0,0 @@ |
||||
from azure.common.credentials import ServicePrincipalCredentials |
||||
from azure.mgmt.resource import ResourceManagementClient |
||||
from azure.mgmt.compute import ComputeManagementClient |
||||
from azure.mgmt.network import NetworkManagementClient |
||||
from azure.mgmt.compute.models import DiskCreateOption |
||||
|
||||
SUBSCRIPTION_ID = '8f969b5c-f8cb-4483-8252-354a929962e0' |
||||
GROUP_NAME = 'myResourceGroup' |
||||
LOCATION = 'westus' |
||||
VM_NAME = 'myomyVM' |
||||
|
||||
def get_credentials(): |
||||
credentials = ServicePrincipalCredentials( |
||||
client_id = '3b75dccc-f500-4195-99df-8da994541d03', |
||||
secret = 'Nj44R21IECrg8Vp/+3MBsXcmQrHcl0SEIpLjPIeOYc4=', |
||||
tenant = '6d22d644-2eec-4dac-9715-7147563a9fe5' |
||||
) |
||||
return credentials |
||||
|
||||
def create_resource_group(resource_group_client): |
||||
resource_group_params = { 'location':LOCATION } |
||||
resource_group_result = resource_group_client.resource_groups.create_or_update( |
||||
GROUP_NAME, |
||||
resource_group_params |
||||
) |
||||
|
||||
def create_availability_set(compute_client): |
||||
avset_params = { |
||||
'location': LOCATION, |
||||
'sku': { 'name': 'Aligned' }, |
||||
'platform_fault_domain_count': 3 |
||||
} |
||||
availability_set_result = compute_client.availability_sets.create_or_update( |
||||
GROUP_NAME, |
||||
'myAVSet', |
||||
avset_params |
||||
) |
||||
|
||||
def create_public_ip_address(network_client): |
||||
public_ip_addess_params = { |
||||
'location': LOCATION, |
||||
'public_ip_allocation_method': 'Dynamic' |
||||
} |
||||
creation_result = network_client.public_ip_addresses.create_or_update( |
||||
GROUP_NAME, |
||||
'myIPAddress', |
||||
public_ip_addess_params |
||||
) |
||||
return creation_result.result() |
||||
|
||||
def create_vnet(network_client): |
||||
vnet_params = { |
||||
'location': LOCATION, |
||||
'address_space': { |
||||
'address_prefixes': ['10.0.0.0/16'] |
||||
} |
||||
} |
||||
creation_result = network_client.virtual_networks.create_or_update( |
||||
GROUP_NAME, |
||||
'myVNet', |
||||
vnet_params |
||||
) |
||||
return creation_result.result() |
||||
|
||||
def create_subnet(network_client): |
||||
subnet_params = { |
||||
'address_prefix': '10.0.0.0/24' |
||||
} |
||||
creation_result = network_client.subnets.create_or_update( |
||||
GROUP_NAME, |
||||
'myVNet', |
||||
'mySubnet', |
||||
subnet_params |
||||
) |
||||
return creation_result.result() |
||||
|
||||
def create_nic(network_client): |
||||
subnet_info = network_client.subnets.get( |
||||
GROUP_NAME, |
||||
'myVNet', |
||||
'mySubnet' |
||||
) |
||||
publicIPAddress = network_client.public_ip_addresses.get( |
||||
GROUP_NAME, |
||||
'myIPAddress' |
||||
) |
||||
nic_params = { |
||||
'location': LOCATION, |
||||
'ip_configurations': [{ |
||||
'name': 'myIPConfig', |
||||
'public_ip_address': publicIPAddress, |
||||
'subnet': { |
||||
'id': subnet_info.id |
||||
} |
||||
}] |
||||
} |
||||
creation_result = network_client.network_interfaces.create_or_update( |
||||
GROUP_NAME, |
||||
'myNic', |
||||
nic_params |
||||
) |
||||
|
||||
return creation_result.result() |
||||
|
||||
def create_vm(network_client, compute_client): |
||||
nic = network_client.network_interfaces.get( |
||||
GROUP_NAME, |
||||
'myNic' |
||||
) |
||||
avset = compute_client.availability_sets.get( |
||||
GROUP_NAME, |
||||
'myAVSet' |
||||
) |
||||
vm_parameters = { |
||||
'location': LOCATION, |
||||
'os_profile': { |
||||
'computer_name': VM_NAME, |
||||
'admin_username': 'azureuser', |
||||
'admin_password': 'Azure12345678' |
||||
}, |
||||
'hardware_profile': { |
||||
'vm_size': 'Standard_DS1' |
||||
}, |
||||
'storage_profile': { |
||||
'image_reference': { |
||||
'publisher': 'MicrosoftWindowsServer', |
||||
'offer': 'WindowsServer', |
||||
'sku': '2012-R2-Datacenter', |
||||
'version': 'latest' |
||||
} |
||||
}, |
||||
'network_profile': { |
||||
'network_interfaces': [{ |
||||
'id': nic.id |
||||
}] |
||||
}, |
||||
'availability_set': { |
||||
'id': avset.id |
||||
} |
||||
} |
||||
creation_result = compute_client.virtual_machines.create_or_update( |
||||
GROUP_NAME, |
||||
VM_NAME, |
||||
vm_parameters |
||||
) |
||||
return creation_result.result() |
||||
|
||||
if __name__ == '__main__': |
||||
credentials = get_credentials() |
||||
resource_group_client = ResourceManagementClient( |
||||
credentials, |
||||
SUBSCRIPTION_ID |
||||
) |
||||
network_client = NetworkManagementClient( |
||||
credentials, |
||||
SUBSCRIPTION_ID |
||||
) |
||||
compute_client = ComputeManagementClient( |
||||
credentials, |
||||
SUBSCRIPTION_ID |
||||
) |
||||
create_resource_group(resource_group_client) |
||||
print('Resource group created....') |
||||
create_availability_set(compute_client) |
||||
print('Availability set created') |
||||
creation_result = create_public_ip_address(network_client) |
||||
print('Public IP created') |
||||
creation_result = create_vnet(network_client) |
||||
print('Virtual Net Created') |
||||
creation_result = create_subnet(network_client) |
||||
print('Subnet created') |
||||
creation_result = create_nic(network_client) |
||||
print('NIC Created') |
||||
creation_result = create_vm(network_client, compute_client) |
||||
print("------------------------------------------------------") |
||||
print("VM Created") |
||||
print(creation_result) |
@ -0,0 +1,99 @@ |
||||
package config |
||||
|
||||
import ( |
||||
"bufio" |
||||
"log" |
||||
"os" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"github.com/simple-rules/harmony-benchmark/p2p" |
||||
) |
||||
|
||||
type ConfigEntry struct { |
||||
IP string |
||||
Port string |
||||
Role string |
||||
ShardID string |
||||
} |
||||
|
||||
type Config struct { |
||||
config []ConfigEntry |
||||
} |
||||
|
||||
func NewConfig() *Config { |
||||
config := Config{} |
||||
return &config |
||||
} |
||||
|
||||
// Gets all the validator peers
|
||||
func (config *Config) GetValidators() []p2p.Peer { |
||||
var peerList []p2p.Peer |
||||
for _, entry := range config.config { |
||||
if entry.Role != "validator" { |
||||
continue |
||||
} |
||||
peer := p2p.Peer{Port: entry.Port, Ip: entry.IP} |
||||
peerList = append(peerList, peer) |
||||
} |
||||
return peerList |
||||
} |
||||
|
||||
// Gets all the leader peers and corresponding shard Ids
|
||||
func (config *Config) GetLeadersAndShardIds() ([]p2p.Peer, []uint32) { |
||||
var peerList []p2p.Peer |
||||
var shardIDs []uint32 |
||||
for _, entry := range config.config { |
||||
if entry.Role == "leader" { |
||||
peerList = append(peerList, p2p.Peer{Ip: entry.IP, Port: entry.Port}) |
||||
val, err := strconv.Atoi(entry.ShardID) |
||||
if err == nil { |
||||
shardIDs = append(shardIDs, uint32(val)) |
||||
} else { |
||||
log.Print("[Generator] Error parsing the shard Id ", entry.ShardID) |
||||
} |
||||
} |
||||
} |
||||
return peerList, shardIDs |
||||
} |
||||
|
||||
func (config *Config) GetClientPeer() *p2p.Peer { |
||||
for _, entry := range config.config { |
||||
if entry.Role != "client" { |
||||
continue |
||||
} |
||||
peer := p2p.Peer{Port: entry.Port, Ip: entry.IP} |
||||
return &peer |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Gets the port of the client node in the config
|
||||
func (config *Config) GetClientPort() string { |
||||
for _, entry := range config.config { |
||||
if entry.Role == "client" { |
||||
return entry.Port |
||||
} |
||||
} |
||||
return "" |
||||
} |
||||
|
||||
// Parse the config file and return a 2d array containing the file data
|
||||
func (config *Config) ReadConfigFile(filename string) error { |
||||
file, err := os.Open(filename) |
||||
defer file.Close() |
||||
if err != nil { |
||||
log.Fatal("Failed to read config file ", filename) |
||||
return err |
||||
} |
||||
fscanner := bufio.NewScanner(file) |
||||
|
||||
result := []ConfigEntry{} |
||||
for fscanner.Scan() { |
||||
p := strings.Split(fscanner.Text(), " ") |
||||
entry := ConfigEntry{p[0], p[1], p[2], p[3]} |
||||
result = append(result, entry) |
||||
} |
||||
config.config = result |
||||
return nil |
||||
} |
@ -1,159 +0,0 @@ |
||||
package configr |
||||
|
||||
import ( |
||||
"bufio" |
||||
"log" |
||||
"os" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"github.com/simple-rules/harmony-benchmark/crypto" |
||||
"github.com/simple-rules/harmony-benchmark/crypto/pki" |
||||
"github.com/simple-rules/harmony-benchmark/p2p" |
||||
"github.com/simple-rules/harmony-benchmark/utils" |
||||
) |
||||
|
||||
type ConfigEntry struct { |
||||
IP string |
||||
Port string |
||||
Role string |
||||
ShardID string |
||||
} |
||||
|
||||
type Configr struct { |
||||
config []ConfigEntry |
||||
} |
||||
|
||||
func NewConfigr() *Configr { |
||||
configr := Configr{} |
||||
return &configr |
||||
} |
||||
|
||||
// Gets all the validator peers
|
||||
func (configr *Configr) GetValidators() []p2p.Peer { |
||||
var peerList []p2p.Peer |
||||
for _, entry := range configr.config { |
||||
if entry.Role != "validator" { |
||||
continue |
||||
} |
||||
peer := p2p.Peer{Port: entry.Port, Ip: entry.IP} |
||||
peerList = append(peerList, peer) |
||||
} |
||||
return peerList |
||||
} |
||||
|
||||
// Gets all the leader peers and corresponding shard Ids
|
||||
func (configr *Configr) GetLeadersAndShardIds() ([]p2p.Peer, []uint32) { |
||||
var peerList []p2p.Peer |
||||
var shardIDs []uint32 |
||||
for _, entry := range configr.config { |
||||
if entry.Role == "leader" { |
||||
peerList = append(peerList, p2p.Peer{Ip: entry.IP, Port: entry.Port}) |
||||
val, err := strconv.Atoi(entry.ShardID) |
||||
if err == nil { |
||||
shardIDs = append(shardIDs, uint32(val)) |
||||
} else { |
||||
log.Print("[Generator] Error parsing the shard Id ", entry.ShardID) |
||||
} |
||||
} |
||||
} |
||||
return peerList, shardIDs |
||||
} |
||||
|
||||
func (configr *Configr) GetClientPeer() *p2p.Peer { |
||||
for _, entry := range configr.config { |
||||
if entry.Role != "client" { |
||||
continue |
||||
} |
||||
peer := p2p.Peer{Port: entry.Port, Ip: entry.IP} |
||||
return &peer |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
// Gets the port of the client node in the config
|
||||
func (configr *Configr) GetClientPort() string { |
||||
for _, entry := range configr.config { |
||||
if entry.Role == "client" { |
||||
return entry.Port |
||||
} |
||||
} |
||||
return "" |
||||
} |
||||
|
||||
// Parse the config file and return a 2d array containing the file data
|
||||
func (configr *Configr) ReadConfigFile(filename string) error { |
||||
file, err := os.Open(filename) |
||||
defer file.Close() |
||||
if err != nil { |
||||
log.Fatal("Failed to read config file ", filename) |
||||
return err |
||||
} |
||||
fscanner := bufio.NewScanner(file) |
||||
|
||||
result := []ConfigEntry{} |
||||
for fscanner.Scan() { |
||||
p := strings.Split(fscanner.Text(), " ") |
||||
entry := ConfigEntry{p[0], p[1], p[2], p[3]} |
||||
result = append(result, entry) |
||||
} |
||||
configr.config = result |
||||
return nil |
||||
} |
||||
|
||||
// GetShardID Gets the shard id of the node corresponding to this ip and port
|
||||
func (configr *Configr) GetShardID(ip, port string) string { |
||||
for _, entry := range configr.config { |
||||
if entry.IP == ip && entry.Port == port { |
||||
return entry.ShardID |
||||
} |
||||
} |
||||
return "N/A" |
||||
} |
||||
|
||||
// GetPeers Gets the validator list
|
||||
func (configr *Configr) GetPeers(ip, port, shardID string) []p2p.Peer { |
||||
var peerList []p2p.Peer |
||||
for _, entry := range configr.config { |
||||
if entry.Role != "validator" || entry.ShardID != shardID { |
||||
continue |
||||
} |
||||
// Get public key deterministically based on ip and port
|
||||
peer := p2p.Peer{Port: entry.Port, Ip: entry.IP} |
||||
setKey(&peer) |
||||
peerList = append(peerList, peer) |
||||
} |
||||
return peerList |
||||
} |
||||
|
||||
// GetLeader Gets the leader of this shard id
|
||||
func (configr *Configr) GetLeader(shardID string) p2p.Peer { |
||||
var leaderPeer p2p.Peer |
||||
for _, entry := range configr.config { |
||||
if entry.Role == "leader" && entry.ShardID == shardID { |
||||
leaderPeer.Ip = entry.IP |
||||
leaderPeer.Port = entry.Port |
||||
setKey(&leaderPeer) |
||||
} |
||||
} |
||||
return leaderPeer |
||||
} |
||||
|
||||
func (configr *Configr) GetConfigEntries() []ConfigEntry { |
||||
return configr.config |
||||
} |
||||
|
||||
func (configr *Configr) GetMyConfigEntry(ip string, port string) *ConfigEntry { |
||||
for _, entry := range configr.config { |
||||
if entry.IP == ip && entry.Port == port { |
||||
return &entry |
||||
} |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func setKey(peer *p2p.Peer) { |
||||
// Get public key deterministically based on ip and port
|
||||
priKey := crypto.Ed25519Curve.Scalar().SetInt64(int64(utils.GetUniqueIdFromPeer(*peer))) // TODO: figure out why using a random hash value doesn't work for private key (schnorr)
|
||||
peer.PubKey = pki.GetPublicKeyFromScalar(priKey) |
||||
} |
@ -0,0 +1,53 @@ |
||||
package p2p |
||||
|
||||
import ( |
||||
"bufio" |
||||
"net" |
||||
"testing" |
||||
) |
||||
|
||||
func setUpTestServer(times int, t *testing.T, conCreated chan bool) { |
||||
t.Parallel() |
||||
ln, _ := net.Listen("tcp", ":8081") |
||||
conCreated <- true |
||||
conn, _ := ln.Accept() |
||||
defer conn.Close() |
||||
|
||||
var ( |
||||
w = bufio.NewWriter(conn) |
||||
) |
||||
for times > 0 { |
||||
times-- |
||||
data, err := ReadMessageContent(conn) |
||||
if err != nil { |
||||
t.Fatalf("error when ReadMessageContent %v", err) |
||||
} |
||||
data = CreateMessage(byte(1), data) |
||||
w.Write(data) |
||||
w.Flush() |
||||
} |
||||
} |
||||
func TestNewNewNode(t *testing.T) { |
||||
times := 100 |
||||
conCreated := make(chan bool) |
||||
go setUpTestServer(times, t, conCreated) |
||||
<-conCreated |
||||
|
||||
conn, _ := net.Dial("tcp", "127.0.0.1:8081") |
||||
|
||||
for times > 0 { |
||||
times-- |
||||
|
||||
myMsg := "minhdoan" |
||||
SendMessageContent(conn, []byte(myMsg)) |
||||
|
||||
data, err := ReadMessageContent(conn) |
||||
if err != nil { |
||||
t.Error("got an error when trying to receive an expected message from server.") |
||||
} |
||||
if string(data) != myMsg { |
||||
t.Error("did not receive expected message") |
||||
} |
||||
} |
||||
conn.Close() |
||||
} |
@ -1,55 +0,0 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"flag" |
||||
"fmt" |
||||
"time" |
||||
|
||||
"github.com/shirou/gopsutil/process" |
||||
"github.com/simple-rules/harmony-benchmark/log" |
||||
) |
||||
|
||||
type profilerSetting struct { |
||||
pid int32 |
||||
shardID string |
||||
} |
||||
|
||||
var ( |
||||
setting profilerSetting |
||||
) |
||||
|
||||
func logPerf() { |
||||
p, _ := process.NewProcess(setting.pid) |
||||
for { |
||||
// log mem usage
|
||||
info, _ := p.MemoryInfo() |
||||
memMap, _ := p.MemoryMaps(false) |
||||
log.Info("Mem Report", "info", info, "map", memMap, "shardID", setting.shardID) |
||||
|
||||
// log cpu usage
|
||||
percent, _ := p.CPUPercent() |
||||
times, _ := p.Times() |
||||
log.Info("CPU Report", "percent", percent, "times", times, "shardID", setting.shardID) |
||||
|
||||
time.Sleep(3 * time.Second) |
||||
} |
||||
} |
||||
|
||||
func main() { |
||||
pid := flag.Int("pid", 0, "process id of the node") |
||||
shardID := flag.String("shard_id", "0", "the shard id of this node") |
||||
logFolder := flag.String("log_folder", "latest", "the folder collecting the logs of this execution") |
||||
flag.Parse() |
||||
|
||||
setting.pid = int32(*pid) |
||||
setting.shardID = *shardID |
||||
logFileName := fmt.Sprintf("./%v/profiler-%v.log", *logFolder, *shardID) |
||||
h := log.MultiHandler( |
||||
log.StdoutHandler, |
||||
log.Must.FileHandler(logFileName, log.JSONFormat()), // Log to file
|
||||
// log.Must.NetHandler("tcp", ":3000", log.JSONFormat()) // Log to remote
|
||||
) |
||||
log.Root().SetHandler(h) |
||||
|
||||
logPerf() |
||||
} |
@ -0,0 +1,48 @@ |
||||
package profiler |
||||
|
||||
import ( |
||||
"time" |
||||
|
||||
"github.com/shirou/gopsutil/process" |
||||
"github.com/simple-rules/harmony-benchmark/log" |
||||
) |
||||
|
||||
type Profiler struct { |
||||
logger log.Logger |
||||
PID int32 |
||||
ShardID string |
||||
proc *process.Process |
||||
} |
||||
|
||||
func NewProfiler(logger log.Logger, pid int, shardID string) *Profiler { |
||||
profiler := Profiler{logger, int32(pid), shardID, nil} |
||||
return &profiler |
||||
} |
||||
|
||||
func (profiler *Profiler) LogMemory() { |
||||
for { |
||||
// log mem usage
|
||||
info, _ := profiler.proc.MemoryInfo() |
||||
memMap, _ := profiler.proc.MemoryMaps(false) |
||||
profiler.logger.Info("Mem Report", "info", info, "map", memMap, "shardID", profiler.ShardID) |
||||
|
||||
time.Sleep(3 * time.Second) |
||||
} |
||||
} |
||||
|
||||
func (profiler *Profiler) LogCPU() { |
||||
for { |
||||
// log cpu usage
|
||||
percent, _ := profiler.proc.CPUPercent() |
||||
times, _ := profiler.proc.Times() |
||||
profiler.logger.Info("CPU Report", "percent", percent, "times", times, "shardID", profiler.ShardID) |
||||
|
||||
time.Sleep(3 * time.Second) |
||||
} |
||||
} |
||||
|
||||
func (profiler *Profiler) Start() { |
||||
profiler.proc, _ = process.NewProcess(profiler.PID) |
||||
go profiler.LogCPU() |
||||
go profiler.LogMemory() |
||||
} |
Loading…
Reference in new issue