Skip to content
This repository has been archived by the owner on Jan 20, 2021. It is now read-only.

Commit

Permalink
Contract support for Fabric v2.0.0 (contributes to #94)
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Stone <sstone1@uk.ibm.com>
  • Loading branch information
Simon Stone committed Jan 16, 2020
1 parent 2041753 commit e996406
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 101 deletions.
25 changes: 24 additions & 1 deletion tasks/manage-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,30 @@
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Install and instantiate contract on all channels
- name: Extract label from package
shell: >
set -o pipefail &&
tar xOf {{ contract.package }} metadata.json
args:
executable: /bin/bash
register: package_metadata
changed_when: False

- name: Set package label
set_fact:
package_label: "{{ (package_metadata.stdout | from_json).label }}"

- name: Determine SHA256 hash of package
stat:
path: "{{ contract.package }}"
checksum_algorithm: sha256
register: package_stats

- name: Set package ID
set_fact:
package_id: "{{ package_label }}:{{ package_stats.stat.checksum }}"

- name: Install, approve and commit all definitions on all channels
include_tasks: manage-contract/channel.yml
with_items: "{{ contract.channels }}"
loop_control:
Expand Down
27 changes: 27 additions & 0 deletions tasks/manage-contract/approve-contract-member.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Select peer to use for approve operations
set_fact:
peer: "{{ member.endorsing_peers[0] }}"

- name: Approve contract
command: >
peer lifecycle chaincode approveformyorg
-C {{ channel.name }}
-n {{ definition.name }}
-v {{ definition.version }}
--package-id {{ package_id }}
--sequence {{ sequence_number }}
-o {{ ibp[channel.orderer.id].hostname }}:{{ ibp[channel.orderer.id].port }}
{{ '--tls' if ibp[channel.orderer.id].protocol == 'grpcs' else '' }}
{{ '--cafile "' + ibp[channel.orderer.id].pem + '"' if ibp[channel.orderer.id].protocol == 'grpcs' else '' }}
{{ '--ordererTLSHostnameOverride ' + ibp[channel.orderer.id].internal_hostname if ibp[channel.orderer.id].internal_hostname is defined else '' }}
environment:
CORE_PEER_ADDRESS: "{{ ibp[peer.id].hostname }}:{{ ibp[peer.id].port }}"
CORE_PEER_MSPCONFIGPATH: "{{ member.wallet }}/{{ member.msp.admin.identity }}"
CORE_PEER_LOCALMSPID: "{{ member.msp.id }}"
CORE_PEER_TLS_ENABLED: "{{ 'true' if peer.tls.enabled else 'false' }}"
CORE_PEER_TLS_ROOTCERT_FILE: "{{ ibp[peer.id].pem if ibp[peer.id].pem is defined }}"
changed_when: True
10 changes: 10 additions & 0 deletions tasks/manage-contract/approve-contract.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Approve contract for all members in channel
include_tasks: approve-contract-member.yml
when: member.endorsing_peers is defined
with_items: "{{ definition.endorsing_members }}"
loop_control:
loop_var: member
54 changes: 54 additions & 0 deletions tasks/manage-contract/calculate-sequence-number.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Select member to use for query operations
set_fact:
member: "{{ definition.endorsing_members[0] }}"

- name: Select peer to use for query operations
set_fact:
peer: "{{ member.endorsing_peers[0] }}"

- name: Retrieve current committed contract list
command: >
peer lifecycle chaincode querycommitted
-C {{ channel.name }}
-n {{ definition.name }}
-O json
environment:
CORE_PEER_ADDRESS: "{{ ibp[peer.id].hostname }}:{{ ibp[peer.id].port }}"
CORE_PEER_MSPCONFIGPATH: "{{ member.wallet }}/{{ member.msp.admin.identity }}"
CORE_PEER_LOCALMSPID: "{{ member.msp.id }}"
CORE_PEER_TLS_ENABLED: "{{ 'true' if peer.tls.enabled else 'false' }}"
CORE_PEER_TLS_ROOTCERT_FILE: "{{ ibp[peer.id].pem if ibp[peer.id].pem is defined }}"
register: querycommitted
failed_when: False
changed_when: False

- name: Handle existing chaincode definition
set_fact:
existing_sequence_number: "{{ (querycommitted.stdout | from_json).sequence }}"
new_sequence_number_reqd: False
when: querycommitted.rc == 0

- name: Handle new chaincode definition
set_fact:
existing_sequence_number: 0
new_sequence_number_reqd: True
when: querycommitted.rc != 0

- name: Determine if version has changed
set_fact:
new_sequence_number_reqd: True
when: not new_sequence_number_reqd and committed_chaincode.version != definition.version

- name: Set next sequence number
set_fact:
sequence_number: "{{ existing_sequence_number + 1 }}"
when: new_sequence_number_reqd

- name: Use existing sequence number
set_fact:
sequence_number: "{{ existing_sequence_number }}"
when: not new_sequence_number_reqd
10 changes: 5 additions & 5 deletions tasks/manage-contract/channel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Install contract on all members peers in the channel
include_tasks: install-contract.yml

- name: Instantiate contract on channel
include_tasks: instantiate-contract.yml
- name: Install, approve and commit all definitions
include_tasks: manage-contract/definition.yml
with_items: "{{ channel.definitions }}"
loop_control:
loop_var: definition
30 changes: 30 additions & 0 deletions tasks/manage-contract/commit-contract.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Select member to use for commit operation
set_fact:
member: "{{ definition.endorsing_members[0] }}"

- name: Select peer to use for commit operation
set_fact:
peer: "{{ member.endorsing_peers[0] }}"

- name: Commit contract
command: >
peer lifecycle chaincode commit
-C {{ channel.name }}
-n {{ definition.name }}
-v {{ definition.version }}
--sequence {{ sequence_number }}
-o {{ ibp[channel.orderer.id].hostname }}:{{ ibp[channel.orderer.id].port }}
{{ '--tls' if ibp[channel.orderer.id].protocol == 'grpcs' else '' }}
{{ '--cafile "' + ibp[channel.orderer.id].pem + '"' if ibp[channel.orderer.id].protocol == 'grpcs' else '' }}
{{ '--ordererTLSHostnameOverride ' + ibp[channel.orderer.id].internal_hostname if ibp[channel.orderer.id].internal_hostname is defined else '' }}
environment:
CORE_PEER_ADDRESS: "{{ ibp[peer.id].hostname }}:{{ ibp[peer.id].port }}"
CORE_PEER_MSPCONFIGPATH: "{{ member.wallet }}/{{ member.msp.admin.identity }}"
CORE_PEER_LOCALMSPID: "{{ member.msp.id }}"
CORE_PEER_TLS_ENABLED: "{{ 'true' if peer.tls.enabled else 'false' }}"
CORE_PEER_TLS_ROOTCERT_FILE: "{{ ibp[peer.id].pem if ibp[peer.id].pem is defined }}"
changed_when: True
16 changes: 16 additions & 0 deletions tasks/manage-contract/definition.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#
# SPDX-License-Identifier: Apache-2.0
#
---
- name: Install contract on all members peers in the channel
include_tasks: install-contract.yml

- name: Calculate sequence number
include_tasks: calculate-sequence-number.yml

- name: Approve contract for all members in the channel
include_tasks: approve-contract.yml

- name: Commit contract in the channel
include_tasks: commit-contract.yml
when: new_sequence_number_reqd
15 changes: 10 additions & 5 deletions tasks/manage-contract/install-contract-peer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@
#
---
- name: Retrieve current installed contract list
command: peer chaincode list --installed
command: peer lifecycle chaincode queryinstalled -O json
environment:
CORE_PEER_ADDRESS: "{{ ibp[peer.id].hostname }}:{{ ibp[peer.id].port }}"
CORE_PEER_MSPCONFIGPATH: "{{ member.wallet }}/{{ member.msp.admin.identity }}"
CORE_PEER_LOCALMSPID: "{{ member.msp.id }}"
CORE_PEER_TLS_ENABLED: "{{ 'true' if peer.tls.enabled else 'false' }}"
CORE_PEER_TLS_ROOTCERT_FILE: "{{ ibp[peer.id].pem if ibp[peer.id].pem is defined }}"
register: chaincode_list
register: queryinstalled
failed_when: False
changed_when: False

- name: Determine if peer has contract installed
set_fact:
contract_installed: "{{ chaincode_list.stdout | join('') is search('Name: ' ~ contract.name ~ ', Version: ' ~ contract.version ~ ',') }}"
installed_chaincodes: "{{
(queryinstalled.stdout | from_json).installed_chaincodes |
default([]) |
selectattr('package_id', 'equalto', package_id) |
list
}}"

- name: Install contract on peer
command: peer chaincode install "{{ contract.package }}"
command: peer lifecycle chaincode install "{{ contract.package }}"
environment:
CORE_PEER_ADDRESS: "{{ ibp[peer.id].hostname }}:{{ ibp[peer.id].port }}"
CORE_PEER_MSPCONFIGPATH: "{{ member.wallet }}/{{ member.msp.admin.identity }}"
CORE_PEER_LOCALMSPID: "{{ member.msp.id }}"
CORE_PEER_TLS_ENABLED: "{{ 'true' if peer.tls.enabled else 'false' }}"
CORE_PEER_TLS_ROOTCERT_FILE: "{{ ibp[peer.id].pem if ibp[peer.id].pem is defined }}"
when: not contract_installed
when: not installed_chaincodes
2 changes: 1 addition & 1 deletion tasks/manage-contract/install-contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
- name: Install contract on all members peers in channel
include_tasks: install-contract-member.yml
when: member.endorsing_peers is defined
with_items: "{{ channel.endorsing_members }}"
with_items: "{{ definition.endorsing_members }}"
loop_control:
loop_var: member
75 changes: 0 additions & 75 deletions tasks/manage-contract/instantiate-contract.yml

This file was deleted.

9 changes: 9 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# SPDX-License-Identifier: Apache-2.0
#

gateways
nodes
wallets
!**/.gitkeep
service-creds.json
Binary file removed tests/fabcar@1.0.0.cds
Binary file not shown.
Binary file added tests/fabcar@1.0.0.tgz
Binary file not shown.
29 changes: 15 additions & 14 deletions tests/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -190,20 +190,21 @@
- *Org2Peer2
anchor_peers:
- *Org2Peer1
# contracts:
# - name: fabcar
# version: 1.0.0
# package: "{{ playbook_dir }}/fabcar@1.0.0.cds"
# channels:
# - <<: *Channel1
# endorsement_policy: "AND('Org1MSP.peer','Org2MSP.peer')"
# endorsing_members:
# - <<: *Org1
# endorsing_peers:
# - <<: *Org1Peer1
# - <<: *Org2
# endorsing_peers:
# - <<: *Org2Peer1
contracts:
- package: "{{ playbook_dir }}/fabcar@1.0.0.tgz"
channels:
- <<: *Channel1
definitions:
- name: fabcar
version: 1.0.0
endorsement_policy: "AND('Org1MSP.peer','Org2MSP.peer')"
endorsing_members:
- <<: *Org1
endorsing_peers:
- <<: *Org1Peer1
- <<: *Org2
endorsing_peers:
- <<: *Org2Peer1
gateways:
- name: Org1 gateway
organization:
Expand Down

0 comments on commit e996406

Please sign in to comment.