mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-18 07:55:10 +00:00
Merge "[FAB-8165] Adding upgrade function to byfn"
This commit is contained in:
commit
831e9bfe80
5 changed files with 305 additions and 31 deletions
|
|
@ -34,13 +34,14 @@ export FABRIC_CFG_PATH=${PWD}
|
|||
# Print the usage message
|
||||
function printHelp () {
|
||||
echo "Usage: "
|
||||
echo " byfn.sh up|down|restart|generate [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-i <imagetag>]"
|
||||
echo " byfn.sh up|down|restart|generate|upgrade [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-i <imagetag>]"
|
||||
echo " byfn.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 " - 'upgrade' - upgrade the network from v1.0.x to v1.1"
|
||||
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)"
|
||||
|
|
@ -58,6 +59,7 @@ function printHelp () {
|
|||
echo " byfn.sh up -c mychannel -s couchdb -i 1.1.0-alpha"
|
||||
echo " byfn.sh up -l node"
|
||||
echo " byfn.sh down -c mychannel"
|
||||
echo " byfn.sh upgrade -c mychannel"
|
||||
echo
|
||||
echo "Taking all defaults:"
|
||||
echo " byfn.sh generate"
|
||||
|
|
@ -141,6 +143,65 @@ function networkUp () {
|
|||
fi
|
||||
}
|
||||
|
||||
# Upgrade the network from v1.0.x to v1.1
|
||||
# Stop the orderer and peers, backup the ledger from orderer and peers, cleanup chaincode containers and images
|
||||
# and relaunch the orderer and peers with latest tag
|
||||
function upgradeNetwork () {
|
||||
if [ ! -d ledgers ]; then
|
||||
echo "ERROR !!!! There is no persisted ledgers directory, did you start your network with -p?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LEDGERS_BACKUP=./ledgers-backup
|
||||
|
||||
# create ledger-backup directory
|
||||
mkdir -p $LEDGERS_BACKUP
|
||||
|
||||
export IMAGE_TAG=$IMAGETAG
|
||||
if [ "${IF_COUCHDB}" == "couchdb" ]; then
|
||||
COMPOSE_FILES="-f $COMPOSE_FILE -f $COMPOSE_FILE_PERSIST -f $COMPOSE_FILE_COUCH"
|
||||
else
|
||||
COMPOSE_FILES="-f $COMPOSE_FILE -f $COMPOSE_FILE_PERSIST"
|
||||
fi
|
||||
|
||||
# removing the cli container
|
||||
docker-compose $COMPOSE_FILES stop cli
|
||||
docker-compose $COMPOSE_FILES up -d --no-deps cli
|
||||
|
||||
echo "Upgrading orderer"
|
||||
docker-compose $COMPOSE_FILES stop orderer.example.com
|
||||
docker cp -a orderer.example.com:/var/hyperledger/production/orderer $LEDGERS_BACKUP/orderer.example.com
|
||||
docker-compose $COMPOSE_FILES up -d --no-deps orderer.example.com
|
||||
|
||||
for PEER in peer0.org1.example.com peer1.org1.example.com peer0.org2.example.com peer1.org2.example.com; do
|
||||
echo "Upgrading peer $PEER"
|
||||
|
||||
# Stop the peer and backup its ledger
|
||||
docker-compose $COMPOSE_FILES stop $PEER
|
||||
docker cp -a $PEER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER/
|
||||
|
||||
# Remove any old containers and images for this peer
|
||||
CC_CONTAINERS=$(docker ps | grep dev-$PEER | awk '{print $1}')
|
||||
if [ -n "$CC_CONTAINERS" ] ; then
|
||||
docker rm -f $CC_CONTAINERS
|
||||
fi
|
||||
CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
|
||||
if [ -n "$CC_IMAGES" ] ; then
|
||||
docker rmi -f $CC_IMAGES
|
||||
fi
|
||||
|
||||
# Start the peer again
|
||||
docker-compose $COMPOSE_FILES up -d --no-deps $PEER
|
||||
done
|
||||
|
||||
docker exec cli scripts/upgrade_to_v11.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR !!!! Test failed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Tear down running network
|
||||
function networkDown () {
|
||||
docker-compose -f $COMPOSE_FILE down
|
||||
|
|
@ -149,6 +210,7 @@ function networkDown () {
|
|||
if [ "$MODE" != "restart" ]; then
|
||||
#Delete any persisted ledgers
|
||||
docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers
|
||||
docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup
|
||||
#Cleanup the chaincode containers
|
||||
clearContainers
|
||||
#Cleanup images
|
||||
|
|
@ -356,6 +418,8 @@ elif [ "$MODE" == "restart" ]; then
|
|||
EXPMODE="Restarting"
|
||||
elif [ "$MODE" == "generate" ]; then
|
||||
EXPMODE="Generating certs and genesis block for"
|
||||
elif [ "$MODE" == "upgrade" ]; then
|
||||
EXPMODE="Upgrading the network"
|
||||
else
|
||||
printHelp
|
||||
exit 1
|
||||
|
|
@ -409,6 +473,8 @@ elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts
|
|||
elif [ "${MODE}" == "restart" ]; then ## Restart the network
|
||||
networkDown
|
||||
networkUp
|
||||
elif [ "${MODE}" == "upgrade" ]; then ## Upgrade the network from v1.0.x to v1.1
|
||||
upgradeNetwork
|
||||
else
|
||||
printHelp
|
||||
exit 1
|
||||
|
|
|
|||
9
first-network/scripts/capabilities.json
Normal file
9
first-network/scripts/capabilities.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"mod_policy": "Admins",
|
||||
"value": {
|
||||
"capabilities": {
|
||||
"V1_1": {}
|
||||
}
|
||||
},
|
||||
"version": "0"
|
||||
}
|
||||
|
|
@ -29,6 +29,9 @@ if [ "$LANGUAGE" = "node" ]; then
|
|||
CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/"
|
||||
fi
|
||||
|
||||
# import utils
|
||||
. scripts/utils.sh
|
||||
|
||||
echo
|
||||
echo "========= Creating config transaction to add org3 to network =========== "
|
||||
echo
|
||||
|
|
@ -36,34 +39,14 @@ echo
|
|||
echo "Installing jq"
|
||||
apt-get -y update && apt-get -y install jq
|
||||
|
||||
echo "Fetching the most recent configuration block for the channel"
|
||||
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c ${CHANNEL_NAME} --tls --cafile ${ORDERER_CA}
|
||||
# Fetch the config for the channel, writing it to config.json
|
||||
fetchChannelConfig ${CHANNEL_NAME} config.json
|
||||
|
||||
echo "Creating config transaction adding org3 to the network"
|
||||
# translate channel configuration block into JSON format
|
||||
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
|
||||
|
||||
# strip away all of the encapsulating wrappers
|
||||
jq .data.data[0].payload.data.config config_block.json > config.json
|
||||
|
||||
# append new org to the configuration
|
||||
# Modify the configuration to append the new org
|
||||
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json
|
||||
|
||||
# translate json config files back to protobuf
|
||||
configtxlator proto_encode --input config.json --type common.Config --output config.pb
|
||||
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
|
||||
|
||||
# get delta between old and new configs
|
||||
configtxlator compute_update --channel_id ${CHANNEL_NAME} --original config.pb --updated modified_config.pb --output org3_update.pb
|
||||
|
||||
# translate protobuf delta to json
|
||||
configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate --output org3_update.json
|
||||
|
||||
# wrap delta in an envelope message
|
||||
echo '{"payload":{"header":{"channel_header":{"channel_id":"'${CHANNEL_NAME}'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json
|
||||
|
||||
# translate json back to protobuf
|
||||
configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb
|
||||
# Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb
|
||||
createConfigUpdate ${CHANNEL_NAME} config.json modified_config.json org3_update_in_envelope.pb
|
||||
|
||||
echo
|
||||
echo "========= Config transaction to add org3 to network created ===== "
|
||||
|
|
@ -71,15 +54,12 @@ echo
|
|||
|
||||
echo "Signing config transaction"
|
||||
echo
|
||||
peer channel signconfigtx -f org3_update_in_envelope.pb
|
||||
signConfigtxAsPeerOrg 1 org3_update_in_envelope.pb
|
||||
|
||||
echo
|
||||
echo "========= Submitting transaction from a different peer (peer0.org2) which also signs it ========= "
|
||||
echo
|
||||
export CORE_PEER_LOCALMSPID="Org2MSP"
|
||||
export 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
|
||||
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
||||
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
|
||||
setGlobals 0 2
|
||||
peer channel update -f org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o orderer.example.com:7050 --tls --cafile ${ORDERER_CA}
|
||||
|
||||
echo
|
||||
|
|
|
|||
168
first-network/scripts/upgrade_to_v11.sh
Executable file
168
first-network/scripts/upgrade_to_v11.sh
Executable file
|
|
@ -0,0 +1,168 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo
|
||||
echo " ____ _____ _ ____ _____ "
|
||||
echo "/ ___| |_ _| / \ | _ \ |_ _|"
|
||||
echo "\___ \ | | / _ \ | |_) | | | "
|
||||
echo " ___) | | | / ___ \ | _ < | | "
|
||||
echo "|____/ |_| /_/ \_\ |_| \_\ |_| "
|
||||
echo
|
||||
echo "Upgrade your first network (BYFN) from v1.0.x to v1.1 end-to-end test"
|
||||
echo
|
||||
CHANNEL_NAME="$1"
|
||||
DELAY="$2"
|
||||
LANGUAGE="$3"
|
||||
TIMEOUT="$4"
|
||||
: ${CHANNEL_NAME:="mychannel"}
|
||||
: ${DELAY:="5"}
|
||||
: ${LANGUAGE:="golang"}
|
||||
: ${TIMEOUT:="10"}
|
||||
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
|
||||
COUNTER=1
|
||||
MAX_RETRY=5
|
||||
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
|
||||
|
||||
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
|
||||
if [ "$LANGUAGE" = "node" ]; then
|
||||
CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/"
|
||||
fi
|
||||
|
||||
echo "Channel name : "$CHANNEL_NAME
|
||||
|
||||
# import utils
|
||||
. scripts/utils.sh
|
||||
|
||||
# addCapabilityToChannel <channel_id> <capabilities_group>
|
||||
# This function pulls the current channel config, modifies it with capabilities
|
||||
# for the specified group, computes the config update, signs, and submits it.
|
||||
addCapabilityToChannel() {
|
||||
CH_NAME=$1
|
||||
GROUP=$2
|
||||
|
||||
setOrdererGlobals
|
||||
|
||||
# Get the current channel config, decode and write it to config.json
|
||||
fetchChannelConfig $CH_NAME config.json
|
||||
|
||||
# Modify the correct section of the config based on capabilities group
|
||||
if [ $GROUP == "orderer" ]; then
|
||||
jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json
|
||||
elif [ $GROUP == "channel" ]; then
|
||||
jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1]}}}' config.json ./scripts/capabilities.json > modified_config.json
|
||||
elif [ $GROUP == "application" ]; then
|
||||
jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json
|
||||
fi
|
||||
|
||||
# Create a config updated for this channel based on the differences between config.json and modified_config.json
|
||||
# write the output to config_update_in_envelope.pb
|
||||
createConfigUpdate "$CH_NAME" config.json modified_config.json config_update_in_envelope.pb
|
||||
|
||||
# Sign, and set the correct identity for submission.
|
||||
if [ $CH_NAME != "testchainid" ] ; then
|
||||
if [ $GROUP == "orderer" ]; then
|
||||
# Modifying the orderer group requires only the Orderer admin to sign.
|
||||
# Prepare to sign the update as the OrdererOrg.Admin
|
||||
setOrdererGlobals
|
||||
elif [ $GROUP == "channel" ]; then
|
||||
# Modifying the channel group requires a majority of application admins and the orderer admin to sign.
|
||||
# Sign with PeerOrg1.Admin
|
||||
signConfigtxAsPeerOrg 1 config_update_in_envelope.pb
|
||||
# Sign with PeerOrg2.Admin
|
||||
signConfigtxAsPeerOrg 2 config_update_in_envelope.pb
|
||||
# Prepare to sign the update as the OrdererOrg.Admin
|
||||
setOrdererGlobals
|
||||
elif [ $GROUP == "application" ]; then
|
||||
# Modifying the application group requires a majority of application admins to sign.
|
||||
# Sign with PeerOrg1.Admin
|
||||
signConfigtxAsPeerOrg 1 config_update_in_envelope.pb
|
||||
# Prepare to sign the update as the PeerOrg2.Admin
|
||||
setGlobals 0 2
|
||||
fi
|
||||
else
|
||||
# For the orderer system channel, only the orderer admin needs sign
|
||||
# which will be attached during the update
|
||||
setOrdererGlobals
|
||||
fi
|
||||
|
||||
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
|
||||
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --cafile $ORDERER_CA
|
||||
else
|
||||
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
|
||||
fi
|
||||
res=$?
|
||||
verifyResult $res "Config update for \"$GROUP\" on \"$CH_NAME\" failed"
|
||||
echo "===================== Config update for \"$GROUP\" on \"$CH_NAME\" is completed ===================== "
|
||||
|
||||
}
|
||||
|
||||
echo "Installing jq"
|
||||
apt-get update
|
||||
apt-get install -y jq
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Config update for /Channel/Orderer on testchainid
|
||||
echo "Config update for /Channel/Orderer on testchainid"
|
||||
addCapabilityToChannel testchainid orderer
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Config update for /Channel on testchainid
|
||||
echo "Config update for /Channel on testchainid"
|
||||
addCapabilityToChannel testchainid channel
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Config update for /Channel/Orderer
|
||||
echo "Config update for /Channel/Orderer on \"$CHANNEL_NAME\""
|
||||
addCapabilityToChannel $CHANNEL_NAME orderer
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Config update for /Channel/Application
|
||||
echo "Config update for /Channel/Application on \"$CHANNEL_NAME\""
|
||||
addCapabilityToChannel $CHANNEL_NAME application
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Config update for /Channel
|
||||
echo "Config update for /Channel on \"$CHANNEL_NAME\""
|
||||
addCapabilityToChannel $CHANNEL_NAME channel
|
||||
|
||||
#Query on chaincode on Peer0/Org1
|
||||
echo "Querying chaincode on org1/peer0..."
|
||||
chaincodeQuery 0 1 90
|
||||
|
||||
#Invoke on chaincode on Peer0/Org1
|
||||
echo "Sending invoke transaction on org1/peer0..."
|
||||
chaincodeInvoke 0 1
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Query on chaincode on Peer0/Org1
|
||||
echo "Querying chaincode on org1/peer0..."
|
||||
chaincodeQuery 0 1 80
|
||||
|
||||
##Invoke on chaincode on Peer0/Org2
|
||||
echo "Sending invoke transaction on org2/peer0..."
|
||||
chaincodeInvoke 0 2
|
||||
|
||||
sleep $DELAY
|
||||
|
||||
#Query on chaincode on Peer0/Org2
|
||||
echo "Querying chaincode on org2/peer0..."
|
||||
chaincodeQuery 0 2 70
|
||||
|
||||
echo
|
||||
echo "===================== All GOOD, End-2-End UPGRADE Scenario execution completed ===================== "
|
||||
echo
|
||||
|
||||
echo
|
||||
echo " _____ _ _ ____ _____ ____ _____ "
|
||||
echo "| ____| | \ | | | _ \ | ____| |___ \ | ____|"
|
||||
echo "| _| | \| | | | | | _____ | _| __) | | _| "
|
||||
echo "| |___ | |\ | | |_| | |_____| | |___ / __/ | |___ "
|
||||
echo "|_____| |_| \_| |____/ |_____| |_____| |_____|"
|
||||
echo
|
||||
|
||||
exit 0
|
||||
|
|
@ -17,6 +17,13 @@ verifyResult () {
|
|||
fi
|
||||
}
|
||||
|
||||
# Set OrdererOrg.Admin globals
|
||||
setOrdererGlobals() {
|
||||
CORE_PEER_LOCALMSPID="OrdererMSP"
|
||||
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
|
||||
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
|
||||
}
|
||||
|
||||
setGlobals () {
|
||||
PEER=$1
|
||||
ORG=$2
|
||||
|
|
@ -171,6 +178,50 @@ chaincodeQuery () {
|
|||
fi
|
||||
}
|
||||
|
||||
# fetchChannelConfig <channel_id> <output_json>
|
||||
# Writes the current channel config for a given channel to a JSON file
|
||||
fetchChannelConfig() {
|
||||
CHANNEL=$1
|
||||
OUTPUT=$2
|
||||
|
||||
setOrdererGlobals
|
||||
|
||||
echo "Fetching the most recent configuration block for the channel"
|
||||
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
|
||||
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL --cafile $ORDERER_CA
|
||||
else
|
||||
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL --tls --cafile $ORDERER_CA
|
||||
fi
|
||||
|
||||
echo "Decoding config block to JSON and isolating config to ${OUTPUT}"
|
||||
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > "${OUTPUT}"
|
||||
}
|
||||
|
||||
# signConfigtxAsPeerOrg <org> <configtx.pb>
|
||||
# Set the peerOrg admin of an org and signing the config update
|
||||
signConfigtxAsPeerOrg() {
|
||||
PEERORG=$1
|
||||
TX=$2
|
||||
setGlobals 0 $PEERORG
|
||||
peer channel signconfigtx -f "${TX}"
|
||||
}
|
||||
|
||||
# createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb>
|
||||
# Takes an original and modified config, and produces the config update tx which transitions between the two
|
||||
createConfigUpdate() {
|
||||
CHANNEL=$1
|
||||
ORIGINAL=$2
|
||||
MODIFIED=$3
|
||||
OUTPUT=$4
|
||||
|
||||
configtxlator proto_encode --input "${ORIGINAL}" --type common.Config > original_config.pb
|
||||
configtxlator proto_encode --input "${MODIFIED}" --type common.Config > modified_config.pb
|
||||
configtxlator compute_update --channel_id "${CHANNEL}" --original original_config.pb --updated modified_config.pb > config_update.pb
|
||||
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate > config_update.json
|
||||
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
|
||||
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope > "${OUTPUT}"
|
||||
}
|
||||
|
||||
chaincodeInvoke () {
|
||||
PEER=$1
|
||||
ORG=$2
|
||||
|
|
|
|||
Loading…
Reference in a new issue