forked from hyperledger/fabric-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-7540] Simplifies Reconfigure Your Network tutorial
This change brings a new set of scripts and configuration files to the first-network sample to make it easier for people to follow the new tutorial on how to add a third org to the network setup in BYFN. To function properly the new Extend You First Network script (eyfn.sh) must be run after byfn.sh is run and with the same parameters. So, valid uses include: ./byfn.sh up ./eyfn.sh up or ./byfn.sh up -c testchannel -s couchdb -l node ./eyfn.sh up -c testchannel -s couchdb -l node A single './eyfn.sh down' command is however necessary to take the whole network down. Patch-set hyperledger#2: fixes ./eyfn.sh down Patch-set hyperledger#3: removed unused option from Usage and spurious whitespaces Patch-set hyperledger#4: added missing test file Change-Id: I9c926b52f2243dda1c5f9368112c314a6c5c6929 Signed-off-by: Arnaud J Le Hors <lehors@us.ibm.com>
- Loading branch information
Showing
9 changed files
with
831 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.