Skip to content

Commit

Permalink
Merge "[FAB-7540] Simplifies Reconfigure Your Network tutorial"
Browse files Browse the repository at this point in the history
  • Loading branch information
mastersingh24 authored and Gerrit Code Review committed Feb 12, 2018
2 parents 4134bc7 + 1d69e9e commit 736c565
Show file tree
Hide file tree
Showing 9 changed files with 831 additions and 155 deletions.
2 changes: 1 addition & 1 deletion first-network/byfn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ else
exit 1
fi

while getopts "h?c:t:d:f:s:l:a?" opt; do
while getopts "h?c:t:d:f:s:l:" opt; do
case "$opt" in
h|\?)
printHelp
Expand Down
64 changes: 64 additions & 0 deletions first-network/docker-compose-couch-org3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

networks:
byfn:

services:
couchdb4:
container_name: couchdb4
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "9984:5984"
networks:
- byfn

peer0.org3.example.com:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
depends_on:
- couchdb4

couchdb5:
container_name: couchdb5
image: hyperledger/fabric-couchdb
# Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password
# for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode.
environment:
- COUCHDB_USER=
- COUCHDB_PASSWORD=
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "10984:5984"
networks:
- byfn

peer1.org3.example.com:
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984
# The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
# provide the credentials for ledger to connect to CouchDB. The username and password must
# match the username and password set for the associated CouchDB.
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=
depends_on:
- couchdb5
310 changes: 310 additions & 0 deletions first-network/eyfn.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
#!/bin/bash
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#

# This script extends the Hyperledger Fabric By Your First Network by
# adding a third organization to the network previously setup in the
# BYFN tutorial.
#

# prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries
# this may be commented out to resolve installed version of tools if desired
export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=${PWD}

# Print the usage message
function printHelp () {
echo "Usage: "
echo " eyfn.sh up|down|restart|generate [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>]"
echo " eyfn.sh -h|--help (print this message)"
echo " <mode> - one of 'up', 'down', 'restart' or 'generate'"
echo " - 'up' - bring up the network with docker-compose up"
echo " - 'down' - clear the network with docker-compose down"
echo " - 'restart' - restart the network"
echo " - 'generate' - generate required certificates and genesis block"
echo " -c <channel name> - channel name to use (defaults to \"mychannel\")"
echo " -t <timeout> - CLI timeout duration in seconds (defaults to 10)"
echo " -d <delay> - delay duration in seconds (defaults to 3)"
echo " -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
echo " -l <language> - the chaincode language: golang (default) or node"
echo
echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:"
echo
echo " eyfn.sh generate -c mychannel"
echo " eyfn.sh up -c mychannel -s couchdb"
echo " eyfn.sh up -l node"
echo " eyfn.sh down -c mychannel"
echo
echo "Taking all defaults:"
echo " eyfn.sh generate"
echo " eyfn.sh up"
echo " eyfn.sh down"
}

# Ask user for confirmation to proceed
function askProceed () {
read -p "Continue? [Y/n] " ans
case "$ans" in
y|Y|"" )
echo "proceeding ..."
;;
n|N )
echo "exiting..."
exit 1
;;
* )
echo "invalid response"
askProceed
;;
esac
}

# Obtain CONTAINER_IDS and remove them
# TODO Might want to make this optional - could clear other containers
function clearContainers () {
CONTAINER_IDS=$(docker ps -aq)
if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
echo "---- No containers available for deletion ----"
else
docker rm -f $CONTAINER_IDS
fi
}

# Delete any images that were generated as a part of this setup
# specifically the following images are often left behind:
# TODO list generated image naming patterns
function removeUnwantedImages() {
DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}')
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
echo "---- No images available for deletion ----"
else
docker rmi -f $DOCKER_IMAGE_IDS
fi
}

# Generate the needed certificates, the genesis block and start the network.
function networkUp () {
# generate artifacts if they don't exist
if [ ! -d "org3-artifacts/crypto-config" ]; then
generateCerts
generateChannelArtifacts
createConfigTx
fi
# start org3 peers
if [ "${IF_COUCHDB}" == "couchdb" ]; then
docker-compose -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH_ORG3 up -d 2>&1
else
docker-compose -f $COMPOSE_FILE_ORG3 up -d 2>&1
fi
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start Org3 network"
exit 1
fi
echo
echo "###############################################################"
echo "############### Have Org3 peers join network ##################"
echo "###############################################################"
docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to have Org3 peers join network"
exit 1
fi
echo
echo "###############################################################"
echo "##### Upgrade chaincode to have Org3 peers on the network #####"
echo "###############################################################"
docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to add Org3 peers on network"
exit 1
fi
# finish by running the test
docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to run test"
exit 1
fi
}

# Tear down running network
function networkDown () {
docker-compose -f $COMPOSE_FILE_ORG3 down
docker-compose -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH_ORG3 down
docker-compose -f $COMPOSE_FILE down
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH down
# Don't remove containers, images, etc if restarting
if [ "$MODE" != "restart" ]; then
#Cleanup the chaincode containers
clearContainers
#Cleanup images
removeUnwantedImages
# remove orderer block and other channel configuration transactions and certs
rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json
# remove the docker-compose yaml file that was customized to the example
rm -f docker-compose-e2e.yaml
fi
}

# Use the CLI container to create the configuration transaction needed to add
# Org3 to the network
function createConfigTx () {
echo
echo "###############################################################"
echo "####### Generate and submit config tx to add Org3 #############"
echo "###############################################################"
docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to create config tx"
exit 1
fi
}

# We use the cryptogen tool to generate the cryptographic material
# (x509 certs) for the new org. After we run the tool, the certs will
# be parked in the BYFN folder titled ``crypto-config``.

# Generates Org3 certs using cryptogen tool
function generateCerts (){
which cryptogen
if [ "$?" -ne 0 ]; then
echo "cryptogen tool not found. exiting"
exit 1
fi
echo
echo "###############################################################"
echo "##### Generate Org3 certificates using cryptogen tool #########"
echo "###############################################################"

(cd org3-artifacts
cryptogen generate --config=./org3-crypto.yaml
if [ "$?" -ne 0 ]; then
echo "Failed to generate certificates..."
exit 1
fi
)
echo
}

# Generate channel configuration transaction
function generateChannelArtifacts() {
which configtxgen
if [ "$?" -ne 0 ]; then
echo "configtxgen tool not found. exiting"
exit 1
fi
echo "##########################################################"
echo "######### Generating Org3 config material ###############"
echo "##########################################################"
(cd org3-artifacts
export FABRIC_CFG_PATH=$PWD
configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json
if [ "$?" -ne 0 ]; then
echo "Failed to generate Org3 config material..."
exit 1
fi
)
cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/
echo
}


# If BYFN wasn't run abort
if [ ! -d crypto-config ]; then
echo
echo "ERROR: Please, run byfn.sh first."
echo
exit 1
fi

# Obtain the OS and Architecture string that will be used to select the correct
# native binaries for your platform
OS_ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
# timeout duration - the duration the CLI should wait for a response from
# another container before giving up
CLI_TIMEOUT=10
#default for delay
CLI_DELAY=3
# channel name defaults to "mychannel"
CHANNEL_NAME="mychannel"
# use this as the default docker-compose yaml definition
COMPOSE_FILE=docker-compose-cli.yaml
#
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
# use this as the default docker-compose yaml definition
COMPOSE_FILE_ORG3=docker-compose-org3.yaml
#
COMPOSE_FILE_COUCH_ORG3=docker-compose-couch-org3.yaml
# use golang as the default language for chaincode
LANGUAGE=golang

# Parse commandline args
if [ "$1" = "-m" ];then # supports old usage, muscle memory is powerful!
shift
fi
MODE=$1;shift
# Determine whether starting, stopping, restarting or generating for announce
if [ "$MODE" == "up" ]; then
EXPMODE="Starting"
elif [ "$MODE" == "down" ]; then
EXPMODE="Stopping"
elif [ "$MODE" == "restart" ]; then
EXPMODE="Restarting"
elif [ "$MODE" == "generate" ]; then
EXPMODE="Generating certs and genesis block for"
else
printHelp
exit 1
fi
while getopts "h?c:t:d:f:s:l:" opt; do
case "$opt" in
h|\?)
printHelp
exit 0
;;
c) CHANNEL_NAME=$OPTARG
;;
t) CLI_TIMEOUT=$OPTARG
;;
d) CLI_DELAY=$OPTARG
;;
f) COMPOSE_FILE=$OPTARG
;;
s) IF_COUCHDB=$OPTARG
;;
l) LANGUAGE=$OPTARG
;;
esac
done

# Announce what was requested

if [ "${IF_COUCHDB}" == "couchdb" ]; then
echo
echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${IF_COUCHDB}'"
else
echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds"
fi
# ask for confirmation to proceed
askProceed

#Create the network using docker compose
if [ "${MODE}" == "up" ]; then
networkUp
elif [ "${MODE}" == "down" ]; then ## Clear the network
networkDown
elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts
generateCerts
generateChannelArtifacts
createConfigTx
elif [ "${MODE}" == "restart" ]; then ## Restart the network
networkDown
networkUp
else
printHelp
exit 1
fi
Loading

0 comments on commit 736c565

Please sign in to comment.