From 1883ae9589af515d5669b5bac6c013725fa06612 Mon Sep 17 00:00:00 2001 From: Arnaud J Le Hors Date: Wed, 20 Dec 2017 23:15:05 +0100 Subject: [PATCH] [FAB-7527] Improves BYFN This change fixes a set of related issues. It fixes the use of the cli timeout setting. It is now merely about the maximum time spent waiting for a response. The e2e script is no longer run from docker-compose but by calling docker exec from byfn.sh and docker-compose now merely has the cli waiting/sleeping for 1000 seconds. This not only allows starting the network without automatically running the e2e script, it also allows byfn.sh to properly end when the e2e script ends rather than hang. It also makes the tutorial simpler. The time the cli container waits/sleeps cannot be changed other than by editing the config file but this shouldn't be a problem. This change also fixes the log output of the e2e script so that peers are consistantly being referenced as in peerX.orgY. In addition, this changes the usage of byfn.sh so that the -m parameter is no longer needed. One merely needs to type "./byfn.sh up" rather than "./byfn.sh -m up". The old way is still supported though, for human backward compatibility. ;-) And by default the answer to the prompt for continuation is "y" so the user can simply continue with a hit of the return key. Change-Id: I3e2409d81018f97ec9306ce6e1ae916d8fe18fec Signed-off-by: Arnaud J Le Hors --- first-network/byfn.sh | 81 ++++++++-------- first-network/docker-compose-cli.yaml | 2 +- first-network/docker-compose-org3.yaml | 2 +- first-network/scripts/script.sh | 122 ++++++++++++++----------- 4 files changed, 112 insertions(+), 95 deletions(-) diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 0fdceade..c6462ed8 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -1,5 +1,4 @@ #!/bin/bash - # # Copyright IBM Corp All Rights Reserved # @@ -35,15 +34,15 @@ export FABRIC_CFG_PATH=${PWD} # Print the usage message function printHelp () { echo "Usage: " - echo " byfn.sh -m up|down|restart|generate [-c ] [-t ] [-d ] [-f ] [-s ]" + echo " byfn.sh up|down|restart|generate [-c ] [-t ] [-d ] [-f ] [-s ]" echo " byfn.sh -h|--help (print this message)" - echo " -m - one of 'up', 'down', 'restart' or 'generate'" + echo " - 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 to use (defaults to \"mychannel\")" - echo " -t - CLI timeout duration in seconds (defaults to 10000)" + echo " -t - CLI timeout duration in seconds (defaults to 10)" echo " -d - delay duration in seconds (defaults to 3)" echo " -f - specify which docker-compose file use (defaults to docker-compose-cli.yaml)" echo " -s - the database backend to use: goleveldb (default) or couchdb" @@ -52,22 +51,22 @@ function printHelp () { echo "Typically, one would first generate the required certificates and " echo "genesis block, then bring up the network. e.g.:" echo - echo " byfn.sh -m generate -c mychannel" - echo " byfn.sh -m up -c mychannel -s couchdb" - echo " byfn.sh -m up -l node" - echo " byfn.sh -m down -c mychannel" + echo " byfn.sh generate -c mychannel" + echo " byfn.sh up -c mychannel -s couchdb" + echo " byfn.sh up -l node" + echo " byfn.sh down -c mychannel" echo echo "Taking all defaults:" - echo " byfn.sh -m generate" - echo " byfn.sh -m up" - echo " byfn.sh -m down" + echo " byfn.sh generate" + echo " byfn.sh up" + echo " byfn.sh down" } # Ask user for confirmation to proceed function askProceed () { - read -p "Continue (y/n)? " ans + read -p "Continue? [Y/n] " ans case "$ans" in - y|Y ) + y|Y|"" ) echo "proceeding ..." ;; n|N ) @@ -113,16 +112,20 @@ function networkUp () { generateChannelArtifacts fi if [ "${IF_COUCHDB}" == "couchdb" ]; then - CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT DELAY=$CLI_DELAY LANG=$LANGUAGE docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH up -d 2>&1 + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH up -d 2>&1 else - CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT DELAY=$CLI_DELAY LANG=$LANGUAGE docker-compose -f $COMPOSE_FILE up -d 2>&1 + docker-compose -f $COMPOSE_FILE up -d 2>&1 fi if [ $? -ne 0 ]; then echo "ERROR !!!! Unable to start network" - docker logs -f cli exit 1 fi - docker logs -f cli + # now run the end to end script + docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT + if [ $? -ne 0 ]; then + echo "ERROR !!!! Test failed" + exit 1 + fi } # Tear down running network @@ -309,7 +312,7 @@ OS_ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/window # timeout duration - the duration the CLI should wait for a response from # another container before giving up CLI_TIMEOUT=10 -#default for delay +# default for delay between commands CLI_DELAY=3 # channel name defaults to "mychannel" CHANNEL_NAME="mychannel" @@ -320,14 +323,30 @@ COMPOSE_FILE_COUCH=docker-compose-couch.yaml # use golang as the default language for chaincode LANGUAGE=golang # Parse commandline args -while getopts "h?m:c:t:d:f:s:l:" opt; do +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:a?" opt; do case "$opt" in h|\?) printHelp exit 0 ;; - m) MODE=$OPTARG - ;; c) CHANNEL_NAME=$OPTARG ;; t) CLI_TIMEOUT=$OPTARG @@ -343,20 +362,6 @@ while getopts "h?m:c:t:d:f:s:l:" opt; do esac done -# 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 - # Announce what was requested if [ "${IF_COUCHDB}" == "couchdb" ]; then @@ -371,13 +376,13 @@ askProceed #Create the network using docker compose if [ "${MODE}" == "up" ]; then networkUp - elif [ "${MODE}" == "down" ]; then ## Clear the network +elif [ "${MODE}" == "down" ]; then ## Clear the network networkDown - elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts +elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts generateCerts replacePrivateKey generateChannelArtifacts - elif [ "${MODE}" == "restart" ]; then ## Restart the network +elif [ "${MODE}" == "restart" ]; then ## Restart the network networkDown networkUp else diff --git a/first-network/docker-compose-cli.yaml b/first-network/docker-compose-cli.yaml index f7053c01..30ad3f36 100644 --- a/first-network/docker-compose-cli.yaml +++ b/first-network/docker-compose-cli.yaml @@ -67,7 +67,7 @@ services: - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer - command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY} ${LANG}; sleep $TIMEOUT' + command: /bin/bash -c 'sleep 1000' volumes: - /var/run/:/host/var/run/ - ./../chaincode/:/opt/gopath/src/github.com/chaincode diff --git a/first-network/docker-compose-org3.yaml b/first-network/docker-compose-org3.yaml index 975d42f8..26c7ba64 100644 --- a/first-network/docker-compose-org3.yaml +++ b/first-network/docker-compose-org3.yaml @@ -70,7 +70,7 @@ services: - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer - command: /bin/bash -c 'sleep 10000' + command: /bin/bash -c 'sleep 1000' volumes: - /var/run/:/host/var/run/ - ./../chaincode/:/opt/gopath/src/github.com/chaincode diff --git a/first-network/scripts/script.sh b/first-network/scripts/script.sh index 8ba3546c..e1bf9cce 100755 --- a/first-network/scripts/script.sh +++ b/first-network/scripts/script.sh @@ -13,7 +13,7 @@ CHANNEL_NAME="$1" DELAY="$2" LANGUAGE="$3" : ${CHANNEL_NAME:="mychannel"} -: ${TIMEOUT:="60"} +: ${TIMEOUT:="10"} : ${LANGUAGE:="golang"} LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` COUNTER=1 @@ -38,21 +38,22 @@ verifyResult () { } setGlobals () { - - if [ $1 -eq 0 -o $1 -eq 1 ] ; then + PEER=$1 + ORG=$2 + if [ $ORG -eq 1 ] ; then CORE_PEER_LOCALMSPID="Org1MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp - if [ $1 -eq 0 ]; then + if [ $PEER -eq 0 ]; then CORE_PEER_ADDRESS=peer0.org1.example.com:7051 else CORE_PEER_ADDRESS=peer1.org1.example.com:7051 fi - else + elif [ $ORG -eq 2 ] ; then CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp - if [ $1 -eq 2 ]; then + if [ $PEER -eq 0 ]; then CORE_PEER_ADDRESS=peer0.org2.example.com:7051 else CORE_PEER_ADDRESS=peer1.org2.example.com:7051 @@ -63,9 +64,9 @@ setGlobals () { } createChannel() { - setGlobals 0 + setGlobals 0 0 - if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then + if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx >&log.txt else peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt @@ -79,13 +80,14 @@ createChannel() { updateAnchorPeers() { PEER=$1 - setGlobals $PEER + ORG=$2 + setGlobals $PEER $ORG if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx >&log.txt - else + else peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt - fi + fi res=$? cat log.txt verifyResult $res "Anchor peer update failed" @@ -96,44 +98,51 @@ updateAnchorPeers() { ## Sometimes Join takes time hence RETRY at least for 5 times joinWithRetry () { + PEER=$1 + ORG=$2 + peer channel join -b $CHANNEL_NAME.block >&log.txt res=$? cat log.txt if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then COUNTER=` expr $COUNTER + 1` - echo "PEER$1 failed to join the channel, Retry after 2 seconds" + echo "peer${PEER}.org${ORG} failed to join the channel, Retry after $DELAY seconds" sleep $DELAY - joinWithRetry $1 + joinWithRetry $PEER $ORG else COUNTER=1 fi - verifyResult $res "After $MAX_RETRY attempts, PEER$ch has failed to Join the Channel" + verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to Join the Channel" } joinChannel () { - for ch in 0 1 2 3; do - setGlobals $ch - joinWithRetry $ch - echo "===================== PEER$ch joined on the channel \"$CHANNEL_NAME\" ===================== " + for org in 1 2; do + for peer in 0 1; do + setGlobals $peer $org + joinWithRetry $peer $org + echo "===================== peer${peer}.org${org} joined on the channel \"$CHANNEL_NAME\" ===================== " sleep $DELAY echo + done done } installChaincode () { PEER=$1 - setGlobals $PEER + ORG=$2 + setGlobals $PEER $ORG peer chaincode install -n mycc -v 1.0 -l ${LANGUAGE} -p ${CC_SRC_PATH} >&log.txt res=$? cat log.txt - verifyResult $res "Chaincode installation on remote peer PEER$PEER has Failed" - echo "===================== Chaincode is installed on remote peer PEER$PEER ===================== " + verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has Failed" + echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== " echo } instantiateChaincode () { PEER=$1 - setGlobals $PEER + ORG=$2 + setGlobals $PEER $ORG # while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful), # lets supply it directly as we know it using the "-o" option if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then @@ -143,15 +152,17 @@ instantiateChaincode () { fi res=$? cat log.txt - verifyResult $res "Chaincode instantiation on PEER$PEER on channel '$CHANNEL_NAME' failed" - echo "===================== Chaincode Instantiation on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== " + verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed" + echo "===================== Chaincode Instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " echo } chaincodeQuery () { PEER=$1 - echo "===================== Querying on PEER$PEER on channel '$CHANNEL_NAME'... ===================== " - setGlobals $PEER + ORG=$2 + setGlobals $PEER $ORG + EXPECTED_RESULT=$3 + echo "===================== Querying on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME'... ===================== " local rc=1 local starttime=$(date +%s) @@ -160,17 +171,17 @@ chaincodeQuery () { while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0 do sleep $DELAY - echo "Attempting to Query PEER$PEER ...$(($(date +%s)-starttime)) secs" + echo "Attempting to Query peer${PEER}.org${ORG} ...$(($(date +%s)-starttime)) secs" peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt test $? -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') - test "$VALUE" = "$2" && let rc=0 + test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 done echo cat log.txt if test $rc -eq 0 ; then - echo "===================== Query on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== " + echo "===================== Query on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " else - echo "!!!!!!!!!!!!!!! Query result on PEER$PEER is INVALID !!!!!!!!!!!!!!!!" + echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!" echo "================== ERROR !!! FAILED to execute End-2-End Scenario ==================" echo exit 1 @@ -179,7 +190,8 @@ chaincodeQuery () { chaincodeInvoke () { PEER=$1 - setGlobals $PEER + ORG=$2 + setGlobals $PEER $ORG # while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful), # lets supply it directly as we know it using the "-o" option if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then @@ -189,8 +201,8 @@ chaincodeInvoke () { fi res=$? cat log.txt - verifyResult $res "Invoke execution on PEER$PEER failed " - echo "===================== Invoke transaction on PEER$PEER on channel '$CHANNEL_NAME' is successful ===================== " + verifyResult $res "Invoke execution on peer${PEER}.org${ORG} failed " + echo "===================== Invoke transaction on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " echo } @@ -204,35 +216,35 @@ joinChannel ## Set the anchor peers for each org in the channel echo "Updating anchor peers for org1..." -updateAnchorPeers 0 +updateAnchorPeers 0 1 echo "Updating anchor peers for org2..." -updateAnchorPeers 2 +updateAnchorPeers 0 2 -## Install chaincode on Peer0/Org1 and Peer2/Org2 -echo "Installing chaincode on org1/peer0..." -installChaincode 0 -echo "Install chaincode on org2/peer2..." -installChaincode 2 +## Install chaincode on peer0.org1 and peer0.org2 +echo "Installing chaincode on peer0.org1..." +installChaincode 0 1 +echo "Install chaincode on peer0.org2..." +installChaincode 0 2 -#Instantiate chaincode on Peer2/Org2 -echo "Instantiating chaincode on org2/peer2..." -instantiateChaincode 2 +# Instantiate chaincode on peer0.org2 +echo "Instantiating chaincode on peer0.org2..." +instantiateChaincode 0 2 -#Query on chaincode on Peer0/Org1 -echo "Querying chaincode on org1/peer0..." -chaincodeQuery 0 100 +# Query chaincode on peer0.org1 +echo "Querying chaincode on peer0.org1..." +chaincodeQuery 0 1 100 -#Invoke on chaincode on Peer0/Org1 -echo "Sending invoke transaction on org1/peer0..." -chaincodeInvoke 0 +# Invoke chaincode on peer0.org1 +echo "Sending invoke transaction on peer0.org1..." +chaincodeInvoke 0 1 -## Install chaincode on Peer3/Org2 -echo "Installing chaincode on org2/peer3..." -installChaincode 3 +## Install chaincode on peer1.org2 +echo "Installing chaincode on peer1.org2..." +installChaincode 1 2 -#Query on chaincode on Peer3/Org2, check if the result is 90 -echo "Querying chaincode on org2/peer3..." -chaincodeQuery 3 90 +# Query on chaincode on peer1.org2, check if the result is 90 +echo "Querying chaincode on peer1.org2..." +chaincodeQuery 1 2 90 echo echo "========= All GOOD, BYFN execution completed =========== "