mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 15:35:09 +00:00
The new microfab release seems to start slower than the previous release. This might be due to a change from solo to raft consensus. This causes failures in the full-stack-asset-transfer appdev tests. Chaincode deployment fails since the channel is not yet available. Instead of increasing the sleep time after launching microfab, this change attempts to wait however long is required by looking for the "Microfab started" message in the container log before proceeding. The test script is also updated to correctly stop the external chaincode process when the script exits. Previously the process ID of the npm command used to lauch the chaincode was captured rather than the actual chaincode process. Signed-off-by: Mark S. Lewis <Mark.S.Lewis@outlook.com>
518 lines
17 KiB
Makefile
518 lines
17 KiB
Makefile
#
|
|
# Copyright contributors to the Hyperledgendary Full Stack Asset Transfer project
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at:
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
#
|
|
|
|
# Main justfile to run all the development scripts
|
|
# To install 'just' see https://github.com/casey/just#installation
|
|
|
|
|
|
###############################################################################
|
|
# COMMON TARGETS #
|
|
###############################################################################
|
|
|
|
|
|
# Ensure all properties are exported as shell env-vars
|
|
set export
|
|
|
|
# set the current directory, and the location of the test dats
|
|
CWDIR := justfile_directory()
|
|
|
|
_default:
|
|
@just -f {{justfile()}} --list
|
|
|
|
# Run the check script to validate tool versions installed
|
|
check:
|
|
${CWDIR}/check.sh
|
|
|
|
cluster_name := env_var_or_default("WORKSHOP_CLUSTER_NAME", "kind")
|
|
cluster_runtime := env_var_or_default("WORKSHOP_CLUSTER_RUNTIME", "kind")
|
|
ingress_domain := env_var_or_default("WORKSHOP_INGRESS_DOMAIN", "localho.st")
|
|
storage_class := env_var_or_default("WORKSHOP_STORAGE_CLASS", "standard")
|
|
chaincode_name := env_var_or_default("WORKSHOP_CHAINCODE_NAME", "asset-transfer")
|
|
internal_repo_endpoint := env_var_or_default("WORKSHOP_INTERNAL_REPO", "localhost:5000")
|
|
external_repo_endpoint := env_var_or_default("WORKSHOP_EXTERNAL_REPO", "localhost:5000")
|
|
cluster_type := env_var_or_default("WORKSHOP_CLUSTER_TYPE", "k8s")
|
|
|
|
|
|
# Start a local KIND cluster with nginx, localhost:5000 registry, and *.localho.st alias in kube DNS
|
|
kind: unkind
|
|
#!/bin/bash
|
|
set -e -o pipefail
|
|
|
|
infrastructure/kind_with_nginx.sh {{cluster_name}}
|
|
ls -lart ~/.kube/config
|
|
chmod o+r ~/.kube/config
|
|
|
|
# check connectivity to local k8s
|
|
kubectl cluster-info &>/dev/null
|
|
|
|
# Shut down the KIND cluster
|
|
unkind:
|
|
#!/bin/bash
|
|
kind delete cluster --name {{cluster_name}}
|
|
|
|
if docker inspect kind-registry &>/dev/null; then
|
|
echo "Stopping container registry"
|
|
docker kill kind-registry
|
|
docker rm kind-registry
|
|
fi
|
|
|
|
# Bring up the nginx ingress controller on the target k8s cluster
|
|
nginx:
|
|
#!/bin/bash
|
|
kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/ingress/{{ cluster_runtime }}
|
|
|
|
sleep 20
|
|
|
|
kubectl wait --namespace ingress-nginx \
|
|
--for=condition=ready pod \
|
|
--selector=app.kubernetes.io/component=controller \
|
|
--timeout=3m
|
|
|
|
# Just start the operator
|
|
operator: operator-crds
|
|
infrastructure/sample-network/network operator
|
|
|
|
# Just start the console
|
|
console: operator
|
|
infrastructure/sample-network/network console
|
|
|
|
# Just install the operator CRDs
|
|
operator-crds: check-kube
|
|
kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/crd
|
|
|
|
|
|
###############################################################################
|
|
# TEST TARGETS
|
|
###############################################################################
|
|
|
|
# Run e2e tests of all scenarios
|
|
test: test-chaincode test-appdev test-cloud # test-ansible
|
|
|
|
# Run an e2e test of the SmartContractDev scenario
|
|
test-chaincode:
|
|
tests/00-chaincode-e2e.sh
|
|
|
|
# Run an e2e test of the ApplicationDev scenario
|
|
test-appdev:
|
|
tests/10-appdev-e2e.sh
|
|
|
|
# Run an e2e test of the CloudNative scenario
|
|
test-cloud:
|
|
tests/20-cloud-e2e.sh
|
|
|
|
# Run tests of the network setup with operator, console, and ansible plays
|
|
test-ansible:
|
|
tests/30-ansible-e2e.sh
|
|
|
|
# Run tests of the console setup using the direct line to kube API controller (not ansible)
|
|
test-console:
|
|
tests/40-console.sh
|
|
|
|
|
|
###############################################################################
|
|
# MICROFAB / DEV TARGETS #
|
|
###############################################################################
|
|
|
|
# Shut down the microfab (uf) instance
|
|
microfab-down:
|
|
#!/bin/bash
|
|
|
|
if docker inspect microfab &>/dev/null; then
|
|
echo "Removing existing microfab container:"
|
|
docker kill microfab
|
|
fi
|
|
|
|
|
|
# Start a micro fab instance and create configuration in _cfg/uf
|
|
microfab: microfab-down
|
|
#!/bin/bash
|
|
set -e -o pipefail
|
|
|
|
export CFG=$CWDIR/_cfg/uf
|
|
export MICROFAB_CONFIG='{
|
|
"endorsing_organizations":[
|
|
{
|
|
"name": "org1"
|
|
},
|
|
{
|
|
"name": "org2"
|
|
}
|
|
],
|
|
"channels":[
|
|
{
|
|
"name": "mychannel",
|
|
"endorsing_organizations":[
|
|
"org1"
|
|
]
|
|
},
|
|
{
|
|
"name": "appchannel",
|
|
"endorsing_organizations":[
|
|
"org1","org2"
|
|
]
|
|
}
|
|
|
|
],
|
|
"capability_level":"V2_5"
|
|
}'
|
|
|
|
mkdir -p $CFG
|
|
echo
|
|
echo "Stating microfab...."
|
|
|
|
timeout 60s bash -c \
|
|
'docker run --name microfab -p 8080:8080 --add-host host.docker.internal:host-gateway --rm -d -e MICROFAB_CONFIG="${MICROFAB_CONFIG}" ghcr.io/hyperledger-labs/microfab:latest \
|
|
&& docker logs -f microfab | grep --max-count=1 "Microfab started"'
|
|
|
|
curl -s http://console.127-0-0-1.nip.io:8080/ak/api/v1/components | weft microfab -w $CFG/_wallets -p $CFG/_gateways -m $CFG/_msp -f
|
|
cat << EOF > $CFG/org1admin.env
|
|
export CORE_PEER_LOCALMSPID=org1MSP
|
|
export CORE_PEER_MSPCONFIGPATH=$CFG/_msp/org1/org1admin/msp
|
|
export CORE_PEER_ADDRESS=org1peer-api.127-0-0-1.nip.io:8080
|
|
export FABRIC_CFG_PATH=$CWDIR/config
|
|
export CORE_PEER_CLIENT_CONNTIMEOUT=15s
|
|
export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s
|
|
EOF
|
|
|
|
cat << EOF > $CFG/org2admin.env
|
|
export CORE_PEER_LOCALMSPID=org2MSP
|
|
export CORE_PEER_MSPCONFIGPATH=$CFG/_msp/org2/org2admin/msp
|
|
export CORE_PEER_ADDRESS=org2peer-api.127-0-0-1.nip.io:8080
|
|
export FABRIC_CFG_PATH=$CWDIR/config
|
|
export CORE_PEER_CLIENT_CONNTIMEOUT=15s
|
|
export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s
|
|
EOF
|
|
|
|
echo
|
|
echo "To get an peer cli environment run:"
|
|
echo
|
|
echo 'source $WORKSHOP_PATH/_cfg/uf/org1admin.env'
|
|
|
|
# Creates a chaincode package and install/approve/commit
|
|
debugcc:
|
|
#!/bin/bash
|
|
set -e -o pipefail
|
|
|
|
export CFG=$CWDIR/_cfg/uf
|
|
|
|
pushd $CWDIR/contracts/asset-transfer-typescript
|
|
|
|
# this is the ip address the peer will use to talk to the CHAINCODE_ID
|
|
# remember this is relative from where the peer is running.
|
|
export CHAINCODE_SERVER_ADDRESS=host.docker.internal:9999
|
|
export CHAINCODE_ID=$(weft chaincode package caas --path . --label asset-transfer --address ${CHAINCODE_SERVER_ADDRESS} --archive asset-transfer.tgz --quiet)
|
|
export CORE_PEER_LOCALMSPID=org1MSP
|
|
export CORE_PEER_MSPCONFIGPATH=$CFG/_msp/org1/org1admin/msp
|
|
export CORE_PEER_ADDRESS=org1peer-api.127-0-0-1.nip.io:8080
|
|
export CORE_PEER_CLIENT_CONNTIMEOUT=15s
|
|
export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s
|
|
|
|
echo "CHAINCODE_ID=${CHAINCODE_ID}"
|
|
|
|
set -x && peer lifecycle chaincode install asset-transfer.tgz && { set +x; } 2>/dev/null
|
|
echo
|
|
set -x && peer lifecycle chaincode approveformyorg --channelID mychannel -o orderer-api.127-0-0-1.nip.io:8080 --name asset-transfer -v 0 --package-id $CHAINCODE_ID --sequence 1 --connTimeout 15s && { set +x; } 2>/dev/null
|
|
echo
|
|
set -x && peer lifecycle chaincode commit --channelID mychannel -o orderer-api.127-0-0-1.nip.io:8080 --name asset-transfer -v 0 --sequence 1 --connTimeout 15s && { set +x; } 2>/dev/null
|
|
echo
|
|
set -x && peer lifecycle chaincode querycommitted --channelID=mychannel && { set +x; } 2>/dev/null
|
|
echo
|
|
popd
|
|
|
|
cat << CC_EOF >> $CFG/org1admin.env
|
|
export CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999
|
|
export CHAINCODE_ID=${CHAINCODE_ID}
|
|
CC_EOF
|
|
|
|
echo "Added CHAINCODE_ID and CHAINCODE_SERVER_ADDRESS to org1admin.env"
|
|
echo
|
|
echo ' source $WORKSHOP_PATH/_cfg/uf/org1admin.env'
|
|
|
|
###############################################################################
|
|
# CLOUD NATIVE TARGETS #
|
|
###############################################################################
|
|
|
|
# Deploy the operator sample network and create a channel
|
|
cloud-network: cloud-network-down check-kube
|
|
infrastructure/sample-network/network up
|
|
|
|
# Tear down the operator sample network
|
|
cloud-network-down:
|
|
infrastructure/sample-network/network down
|
|
|
|
# Create 'mychannel'
|
|
cloud-channel:
|
|
infrastructure/sample-network/network channel create
|
|
|
|
# Check that the cloud setup has been performed
|
|
check-setup: check
|
|
|
|
# Check that the k8s API controller is ready
|
|
check-kube: check-setup
|
|
checks/check-kube.sh
|
|
|
|
# Check that the sample network and channel have been deployed
|
|
check-network: check-kube
|
|
checks/check-network.sh
|
|
|
|
# Check that the smart contract has been deployed
|
|
check-chaincode: check-network
|
|
checks/check-chaincode.sh
|
|
|
|
# Create 'rest-easy'
|
|
cloud-rest-easy:
|
|
infrastructure/sample-network/network rest-easy
|
|
# Create 'frontend'
|
|
cloud-frontend:
|
|
infrastructure/sample-network/network frontend
|
|
|
|
###############################################################################
|
|
# ANSIBLE PLAYBOOK TARGETS #
|
|
###############################################################################
|
|
|
|
ansible_image := env_var_or_default("ANSIBLE_IMAGE", "ghcr.io/hyperledger-labs/fabric-ansible:latest")
|
|
namespace := env_var_or_default("WORKSHOP_NAMESPACE", "fabricinfra")
|
|
|
|
# just set up everything with Ansible
|
|
ansible-doit: ansible-review-config ansible-operator ansible-console ansible-network
|
|
|
|
|
|
# Review the Ansible Blockchain Collection configuration in _cfg/
|
|
ansible-review-config:
|
|
#!/bin/bash
|
|
mkdir -p ${CWDIR}/_cfg
|
|
rm -rf ${CWDIR}/_cfg/* || true
|
|
|
|
cp ${CWDIR}/infrastructure/configuration/*.yml ${CWDIR}/_cfg
|
|
|
|
cat ${CWDIR}/infrastructure/configuration/operator-console-vars.yml | envsubst > ${CWDIR}/_cfg/operator-console-vars.yml
|
|
|
|
echo ""
|
|
echo ">> Fabric Common Configuration"
|
|
echo ""
|
|
cat ${CWDIR}/_cfg/fabric-common-vars.yml
|
|
|
|
echo ""
|
|
echo ">> Fabric Org1 Configuration"
|
|
echo ""
|
|
cat ${CWDIR}/_cfg/fabric-org1-vars.yml
|
|
|
|
echo ""
|
|
echo ">> Fabric Org2 Configuration"
|
|
echo ""
|
|
cat ${CWDIR}/_cfg/fabric-org2-vars.yml
|
|
|
|
echo ""
|
|
echo ">> Fabric Orderer Configuration"
|
|
echo ""
|
|
cat ${CWDIR}/_cfg/fabric-ordering-org-vars.yml
|
|
|
|
echo ""
|
|
echo ">> Fabric Operations Console Configuration"
|
|
echo ""
|
|
cat ${CWDIR}/_cfg/operator-console-vars.yml
|
|
echo ""
|
|
|
|
# Start the Kubernetes fabric-operator with the Ansible Blockchain Collection
|
|
ansible-ingress:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
docker run \
|
|
--rm \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
-v $(pwd)/infrastructure/kind_console_ingress:/playbooks \
|
|
--network=host ${EXTRAS} \
|
|
--workdir /playbooks \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/90-KIND-ingress.yml
|
|
|
|
|
|
|
|
# Start the Kubernetes fabric-operator with the Ansible Blockchain Collection
|
|
ansible-operator:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
docker run \
|
|
--rm \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
-v $(pwd)/infrastructure/operator_console_playbooks:/playbooks ${EXTRAS} \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/01-operator-install.yml
|
|
|
|
# Start the Fabric Operations Console with the Ansible Blockchain Collection
|
|
ansible-console:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
docker run \
|
|
--rm \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v $(pwd)/infrastructure/operator_console_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/02-console-install.yml
|
|
|
|
ansible-auth:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
AUTH=$(curl -X POST https://{{namespace}}-hlf-console-console.{{ingress_domain}}:443/ak/api/v2/permissions/keys -u admin:password -k -H 'Content-Type: application/json' -d '{"roles": ["writer", "manager"],"description": "newkey"}')
|
|
KEY=$(echo $AUTH | jq .api_key | tr -d '"')
|
|
SECRET=$(echo $AUTH | jq .api_secret | tr -d '"')
|
|
|
|
echo "Writing authentication file for Ansible based IBP (Software) network building"
|
|
cat << EOF > $CWDIR/_cfg/auth-vars.yml
|
|
api_key: $KEY
|
|
api_endpoint: https://{{namespace}}-hlf-console-console.{{ingress_domain}}/
|
|
api_authtype: basic
|
|
api_secret: $SECRET
|
|
EOF
|
|
cat ${CWDIR}/_cfg/auth-vars.yml
|
|
|
|
|
|
# Build a sample Fabric network with the Ansible Blockchain Collection
|
|
ansible-network: ansible-auth
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
docker run \
|
|
--rm \
|
|
-u $(id -u) \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/infrastructure/fabric_network_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/00-complete.yml
|
|
|
|
|
|
# Bring down the sample network created with the Ansible Blockchain Collection
|
|
ansible-network-down:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
kubectl delete namespace {{ namespace }} --ignore-not-found
|
|
|
|
|
|
# Build a chaincode package with Ansible Blockchain Collection
|
|
ansible-build-chaincode:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
pushd ${CWDIR}/contracts/asset-transfer-typescript
|
|
|
|
if [ "{{cluster_runtime}}" = "openshift" ]; then
|
|
export IMAGE_NAME="{{namespace}}/{{chaincode_name}}"
|
|
else
|
|
export IMAGE_NAME="{{chaincode_name}}"
|
|
fi
|
|
DOCKER_BUILDKIT=1 docker build -t {{external_repo_endpoint}}/${IMAGE_NAME} . --target k8s
|
|
docker push {{external_repo_endpoint}}/${IMAGE_NAME}
|
|
|
|
# note the double { } for escaping
|
|
export IMG_SHA=$(docker inspect --format='{{{{index .RepoDigests 0}}' {{external_repo_endpoint}}/${IMAGE_NAME} | cut -d'@' -f2)
|
|
weft chaincode package k8s --name {{internal_repo_endpoint}}/${IMAGE_NAME} --digest ${IMG_SHA} --label {{chaincode_name}}
|
|
mv {{chaincode_name}}.tgz ${CWDIR}/_cfg
|
|
popd
|
|
|
|
|
|
# Deploy a chaincode package with the Ansible Blockchain Collection
|
|
ansible-deploy-chaincode:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
# cp ${CWDIR}/contracts/asset-transfer-typescript/asset-transfer-chaincode-vars.yml ${CWDIR}/_cfg
|
|
docker run \
|
|
--rm \
|
|
-u $(id -u) \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/infrastructure/production_chaincode_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/19-install-and-approve-chaincode.yml
|
|
|
|
docker run \
|
|
--rm \
|
|
-u $(id -u) \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/infrastructure/production_chaincode_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/20-install-and-approve-chaincode.yml
|
|
|
|
docker run \
|
|
--rm \
|
|
-u $(id -u) \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/infrastructure/production_chaincode_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/21-commit-chaincode.yml
|
|
|
|
# Creates a new identity for an application to use
|
|
ansible-ready-application:
|
|
#!/bin/bash
|
|
set -ex -o pipefail
|
|
|
|
export EXTRAS=""
|
|
if [ -f "/_cfg/k8s_context.yaml" ]; then
|
|
export EXTRAS=" -e KUBECONFIG=/_cfg/k8s_context.yaml"
|
|
fi
|
|
|
|
docker run \
|
|
--rm \
|
|
-u $(id -u) \
|
|
-v ${HOME}/.kube/:/home/hlf-user/.kube/ \
|
|
-v ${CWDIR}/infrastructure/production_chaincode_playbooks:/playbooks ${EXTRAS} \
|
|
-v ${CWDIR}/_cfg:/_cfg \
|
|
--network=host \
|
|
{{ansible_image}} \
|
|
ansible-playbook /playbooks/22-register-application.yml
|