Skip to content

Commit 2b7ecc9

Browse files
authored
Merge pull request #683 from H-ario-m/fix-677-node-selection
Fix chaincode installation to use selected node ID
2 parents d67c442 + 2166ac1 commit 2b7ecc9

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

src/api-engine/api/routes/chaincode/views.py

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
from rest_framework.decorators import action
77
from rest_framework.permissions import IsAuthenticated
88
import os
9-
import tempfile, shutil, tarfile, json
9+
import tempfile
10+
import shutil
11+
import tarfile
12+
import json
1013

1114
from drf_yasg.utils import swagger_auto_schema
1215
from api.config import FABRIC_CHAINCODE_STORE
@@ -35,8 +38,10 @@
3538
import hashlib
3639
import logging
3740

41+
3842
LOG = logging.getLogger(__name__)
3943

44+
4045
class ChainCodeViewSet(viewsets.ViewSet):
4146
"""Class represents Channel related operations."""
4247
permission_classes = [IsAuthenticated, ]
@@ -52,13 +57,19 @@ def _read_cc_pkg(self, pk, filename, ccpackage_path):
5257
meta_path = os.path.join(ccpackage_path, "metadata.json")
5358
# extract metadata file
5459
with tarfile.open(os.path.join(ccpackage_path, filename)) as tared_file:
55-
metadata_file = tared_file.getmember("metadata.json")
56-
tared_file.extract(metadata_file, path=ccpackage_path)
57-
58-
with open(meta_path, 'r') as f:
59-
metadata = json.load(f)
60-
language = metadata["type"]
61-
label = metadata["label"]
60+
metadata_file = None
61+
for member in tared_file.getmembers():
62+
if member.name.endswith("metadata.json"):
63+
metadata_file = member
64+
break
65+
66+
if metadata_file is not None:
67+
# Extract the metadata file
68+
metadata_content = tared_file.extractfile(
69+
metadata_file).read().decode("utf-8")
70+
metadata = json.loads(metadata_content)
71+
language = metadata["type"]
72+
label = metadata["label"]
6273

6374
if os.path.exists(meta_path):
6475
os.remove(meta_path)
@@ -111,7 +122,10 @@ def list(self, request):
111122
]
112123
response = ChaincodeListResponse(
113124
{"data": chanincodes_list, "total": chaincodes.count()})
114-
return Response(data=ok(response.data), status=status.HTTP_200_OK)
125+
return Response(
126+
data=ok(
127+
response.data),
128+
status=status.HTTP_200_OK)
115129
except Exception as e:
116130
return Response(
117131
err(e.args), status=status.HTTP_400_BAD_REQUEST
@@ -145,22 +159,23 @@ def package(self, request):
145159
if member.name.endswith("metadata.json"):
146160
metadata_file = member
147161
break
148-
162+
149163
if metadata_file is not None:
150164
# Extract the metadata file
151-
metadata_content = tar.extractfile(metadata_file).read().decode("utf-8")
165+
metadata_content = tar.extractfile(
166+
metadata_file).read().decode("utf-8")
152167
metadata = json.loads(metadata_content)
153168
label = metadata.get("label")
154169
else:
155170
return Response(
156-
err("Metadata file not found in the chaincode package."), status=status.HTTP_400_BAD_REQUEST
157-
)
171+
err("Metadata file not found in the chaincode package."),
172+
status=status.HTTP_400_BAD_REQUEST)
158173

159174
org = request.user.organization
160175
# qs = Node.objects.filter(type="peer", organization=org)
161176
# if not qs.exists():
162177
# return Response(
163-
# err("at least 1 peer node is required for the chaincode package upload."),
178+
# err("at least 1 peer node is required for the chaincode package upload."),
164179
# status=status.HTTP_400_BAD_REQUEST
165180
# )
166181
# peer_node = qs.first()
@@ -169,7 +184,7 @@ def package(self, request):
169184
# return_code, content = peer_channel_cli.lifecycle_calculatepackageid(temp_cc_path)
170185
# if (return_code != 0):
171186
# return Response(
172-
# err("calculate packageid failed for {}.".format(content)),
187+
# err("calculate packageid failed for {}.".format(content)),
173188
# status=status.HTTP_400_BAD_REQUEST
174189
# )
175190
# packageid = content.strip()
@@ -185,7 +200,7 @@ def package(self, request):
185200
cc = ChainCode.objects.filter(package_id=packageid)
186201
if cc.exists():
187202
return Response(
188-
err("package with id {} already exists.".format(packageid)),
203+
err("package with id {} already exists.".format(packageid)),
189204
status=status.HTTP_400_BAD_REQUEST
190205
)
191206

@@ -206,8 +221,9 @@ def package(self, request):
206221

207222
# start thread to read package meta info, update db
208223
try:
209-
threading.Thread(target=self._read_cc_pkg,
210-
args=(uuid, file.name, ccpackage_path)).start()
224+
threading.Thread(
225+
target=self._read_cc_pkg,
226+
args=(uuid, file.name, ccpackage_path)).start()
211227
except Exception as e:
212228
LOG.exception("Failed Threading")
213229
raise e
@@ -231,6 +247,8 @@ def package(self, request):
231247
@action(detail=False, methods=['post'])
232248
def install(self, request):
233249
chaincode_id = request.data.get("id")
250+
# Get the selected node ID from request
251+
node_id = request.data.get("node")
234252
try:
235253
cc_targz = ""
236254
file_path = os.path.join(FABRIC_CHAINCODE_STORE, chaincode_id)
@@ -239,16 +257,31 @@ def install(self, request):
239257
break
240258

241259
org = request.user.organization
242-
qs = Node.objects.filter(type="peer", organization=org)
243-
if not qs.exists():
244-
raise ResourceNotFound("Peer Does Not Exist")
245-
peer_node = qs.first()
260+
261+
# If node_id is provided, get that specific node
262+
if node_id:
263+
try:
264+
peer_node = Node.objects.get(
265+
id=node_id, type="peer", organization=org)
266+
except Node.DoesNotExist:
267+
return Response(
268+
err("Selected peer node not found or not authorized."),
269+
status=status.HTTP_404_NOT_FOUND
270+
)
271+
else:
272+
# Fallback to first peer if no node selected
273+
qs = Node.objects.filter(type="peer", organization=org)
274+
if not qs.exists():
275+
raise ResourceNotFound
276+
peer_node = qs.first()
246277

247278
envs = init_env_vars(peer_node, org)
248279
peer_channel_cli = PeerChainCode(**envs)
249280
res = peer_channel_cli.lifecycle_install(cc_targz)
250281
if res != 0:
251-
return Response(err("install chaincode failed."), status=status.HTTP_400_BAD_REQUEST)
282+
return Response(
283+
err("install chaincode failed."),
284+
status=status.HTTP_400_BAD_REQUEST)
252285
except Exception as e:
253286
return Response(
254287
err(e.args), status=status.HTTP_400_BAD_REQUEST

src/dashboard/src/pages/ChainCode/forms/InstallForm.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/
14
import React, { useState, useEffect } from 'react';
25
import { injectIntl, useIntl } from 'umi';
36
import { Modal, message, Select, Form, Tag, Input } from 'antd';
@@ -23,7 +26,15 @@ const InstallForm = props => {
2326
useEffect(() => {
2427
async function fecthData() {
2528
const response = await listNode();
26-
setNodes(response.data.data.map(node => ({ label: node.name, value: node.id })));
29+
// Filter out orderer nodes, only allow peer nodes for chaincode installation
30+
setNodes(
31+
response.data.data
32+
.filter(node => node.type === 'peer')
33+
.map(node => ({
34+
label: node.name,
35+
value: node.id,
36+
}))
37+
);
2738
}
2839
fecthData();
2940
}, []);

0 commit comments

Comments
 (0)