diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/find-and-replace-fabric-logging-spec.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/find-and-replace-fabric-logging-spec.ts new file mode 100644 index 0000000000..9e903aa4ea --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/find-and-replace-fabric-logging-spec.ts @@ -0,0 +1,25 @@ +import { Checks } from "@hyperledger/cactus-common"; + +const PATTERN_FABRIC_CORE_LOGGING_LEVEL = new RegExp( + `\\s+(-e|--env)\\s+CORE_LOGGING_LEVEL='?"?\\w+'?"?\\s+`, + "gmi", +); + +const PATTERN_FABRIC_LOGGING_SPEC = new RegExp( + `FABRIC_LOGGING_SPEC=('?"?\\w+'?"?)`, + "gmi", +); + +export function findAndReplaceFabricLoggingSpec( + input: string, + newLogLevel: string, +): string { + Checks.nonBlankString(input, `findAndReplaceFabricLoggingSpec() arg1`); + Checks.nonBlankString(newLogLevel, `findAndReplaceFabricLoggingSpec() arg2`); + return input + .replace(PATTERN_FABRIC_CORE_LOGGING_LEVEL, " ") + .replace( + PATTERN_FABRIC_LOGGING_SPEC, + " FABRIC_LOGGING_SPEC= ".concat(newLogLevel), + ); +} diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/ssh-exec.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/ssh-exec.ts new file mode 100644 index 0000000000..b61a4a20de --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/common/ssh-exec.ts @@ -0,0 +1,30 @@ +import { + NodeSSH, + SSHExecCommandOptions, + SSHExecCommandResponse, +} from "node-ssh"; +import { RuntimeError } from "run-time-error-cjs"; + +import { Logger } from "@hyperledger/cactus-common"; + +import { isSshExecOk } from "./is-ssh-exec-ok"; + +export async function sshExec( + ctx: { readonly log: Logger }, + cmd: string, + label: string, + ssh: NodeSSH, + sshCmdOptions: SSHExecCommandOptions, +): Promise { + ctx.log.debug(`${label} CMD: ${cmd}`); + const cmdRes = await ssh.execCommand(cmd, sshCmdOptions); + ctx.log.debug(`${label} CMD Response .code: %o`, cmdRes.code); + ctx.log.debug(`${label} CMD Response .signal: %o`, cmdRes.signal); + ctx.log.debug(`${label} CMD Response .stderr: %s`, cmdRes.stderr); + ctx.log.debug(`${label} CMD Response .stdout: %s`, cmdRes.stdout); + + if (!isSshExecOk(cmdRes)) { + throw new RuntimeError(`Expected ${label} cmdRes.code as null or 0`); + } + return cmdRes; +} diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts new file mode 100644 index 0000000000..d3c64b85fb --- /dev/null +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6.ts @@ -0,0 +1,355 @@ +import path from "path"; +import temp from "temp"; +import fs from "fs/promises"; + +import { + NodeSSH, + SSHExecCommandOptions, + SSHExecCommandResponse, +} from "node-ssh"; + +import { Checks, Logger } from "@hyperledger/cactus-common"; +import { FABRIC_25_LTS_FABRIC_SAMPLES__ORDERER_TLS_ROOTCERT_FILE_ORG_1 } from "@hyperledger/cactus-test-tooling"; + +import { + DeployContractGoSourceV1Request, + DeployContractGoSourceV1Response, +} from "../generated/openapi/typescript-axios/api"; +import { IPluginLedgerConnectorFabricOptions } from "../plugin-ledger-connector-fabric"; +import { sshExec } from "../common/ssh-exec"; +import { findAndReplaceFabricLoggingSpec } from "../common/find-and-replace-fabric-logging-spec"; +import { IQueryInstalledResponse } from "../peer/i-query-installed-response"; +import { isSshExecOk } from "../common/is-ssh-exec-ok"; +import { IQueryCommittedResponse } from "../peer/i-query-committed-response"; + +/** + * Constant value holding the default $GOPATH in the Fabric CLI container as + * observed on fabric deployments that are produced by the official examples + * found in the https://github.com/hyperledger/fabric-samples repository. + */ +export const K_DEFAULT_CLI_CONTAINER_GO_PATH = "/opt/gopath/"; + +export interface IDeployContractGoSourceImplFabricV256Context { + readonly log: Logger; + readonly className: string; + readonly dockerBinary: string; + readonly opts: IPluginLedgerConnectorFabricOptions; +} + +/** + * @param req The object containing all the necessary metadata and parameters + * in order to have the contract deployed. + */ +export async function deployContractGoSourceImplFabricV256( + ctx: IDeployContractGoSourceImplFabricV256Context, + req: DeployContractGoSourceV1Request, +): Promise { + const { log, className, dockerBinary } = ctx; + const fnTag = `${className}#deployContractGoSourceImplFabricV256()`; + + const cliContainerGoPath = + ctx.opts.cliContainerGoPath || K_DEFAULT_CLI_CONTAINER_GO_PATH; + + const ssh = new NodeSSH(); + await ssh.connect(ctx.opts.sshConfig); + log.debug(`SSH connection OK`); + + try { + log.debug(`${fnTag} Deploying .go source: ${req.goSource.filename}`); + + Checks.truthy(req.goSource, `${fnTag}:req.goSource`); + + temp.track(); + const tmpDirPrefix = `hyperledger-cacti-${className}`; + const tmpDirPath = temp.mkdirSync(tmpDirPrefix); + + // The module name of the chain-code, for example this will extract + // ccName to be "hello-world" from a filename of "hello-world.go" + const inferredModuleName = path.basename(req.goSource.filename, ".go"); + log.debug(`Inferred module name: ${inferredModuleName}`); + const ccName = req.moduleName || inferredModuleName; + log.debug(`Determined ChainCode name: ${ccName}`); + + const remoteDirPath = path.join(cliContainerGoPath, "src/", ccName); + log.debug(`Remote dir path on CLI container: ${remoteDirPath}`); + + const localFilePath = path.join(tmpDirPath, req.goSource.filename); + await fs.writeFile(localFilePath, req.goSource.body, "base64"); + + const remoteFilePath = path.join(remoteDirPath, req.goSource.filename); + + log.debug(`SCP from/to %o => %o`, localFilePath, remoteFilePath); + await ssh.putFile(localFilePath, remoteFilePath); + log.debug(`SCP OK %o`, remoteFilePath); + + const sshOpts: SSHExecCommandOptions = { + execOptions: { + pty: true, + env: { + // just in case go modules would be otherwise disabled + GO111MODULE: "on", + FABRIC_LOGGING_SPEC: "DEBUG", + }, + }, + cwd: remoteDirPath, + }; + + const dockerCliExecEnv = Object.entries(ctx.opts.cliContainerEnv) + .map(([key, value]) => `--env ${key}=${value}`) + .join(" "); + + const dockerBuildCmd = + `${dockerBinary} exec ` + + dockerCliExecEnv + + ` --workdir=${remoteDirPath}` + + ` cli `; + + await sshExec( + ctx, + `${dockerBinary} exec cli mkdir -p ${remoteDirPath}/`, + "Create ChainCode project (go module) directory", + ssh, + sshOpts, + ); + + await sshExec( + ctx, + `${dockerBinary} exec cli go version`, + "Print go version", + ssh, + sshOpts, + ); + + const copyToCliCmd = `${dockerBinary} cp ${remoteFilePath} cli:${remoteFilePath}`; + log.debug(`Copy to CLI Container CMD: ${copyToCliCmd}`); + const copyToCliRes = await ssh.execCommand(copyToCliCmd, sshOpts); + log.debug(`Copy to CLI Container CMD Response: %o`, copyToCliRes); + Checks.truthy(copyToCliRes.code === 0, `copyToCliRes.code === 0`); + + { + const goModInitCmd = `${dockerBuildCmd} go mod init ${ccName}`; + log.debug(`go mod init CMD: ${goModInitCmd}`); + const goModInitRes = await ssh.execCommand(goModInitCmd, sshOpts); + log.debug(`go mod init CMD Response: %o`, goModInitRes); + Checks.truthy(goModInitRes.code === 0, `goModInitRes.code === 0`); + } + + const pinnedDeps = req.pinnedDeps || []; + for (const dep of pinnedDeps) { + const goGetCmd = `${dockerBuildCmd} go get ${dep}`; + log.debug(`go get CMD: ${goGetCmd}`); + const goGetRes = await ssh.execCommand(goGetCmd, sshOpts); + log.debug(`go get CMD Response: %o`, goGetRes); + Checks.truthy(goGetRes.code === 0, `goGetRes.code === 0`); + } + + { + const goModTidyCmd = `${dockerBuildCmd} go mod tidy`; + log.debug(`go mod tidy CMD: ${goModTidyCmd}`); + const goModTidyRes = await ssh.execCommand(goModTidyCmd, sshOpts); + log.debug(`go mod tidy CMD Response: %o`, goModTidyRes); + Checks.truthy(goModTidyRes.code === 0, `goModTidyRes.code === 0`); + } + + { + const goVendorCmd = `${dockerBuildCmd} go mod vendor`; + log.debug(`go mod vendor CMD: ${goVendorCmd}`); + const goVendorRes = await ssh.execCommand(goVendorCmd, sshOpts); + log.debug(`go mod vendor CMD Response: %o`, goVendorRes); + Checks.truthy(goVendorRes.code === 0, `goVendorRes.code === 0`); + } + + { + const goBuildCmd = `${dockerBuildCmd} go build`; + log.debug(`go build CMD: ${goBuildCmd}`); + const goBuildRes = await ssh.execCommand(goBuildCmd, sshOpts); + log.debug(`go build CMD Response: %o`, goBuildRes); + Checks.truthy(goBuildRes.code === 0, `goBuildRes.code === 0`); + } + + let success = true; + + const installationCommandResponses: SSHExecCommandResponse[] = []; + const ccSequence = 1; + const orderer = "orderer.example.com:7050"; + const ordererTLSHostnameOverride = "orderer.example.com"; + + const ccPkgCmd = + `${dockerBuildCmd} peer lifecycle chaincode package ${ccName}.tar.gz ` + + ` --path ${remoteDirPath} ` + + ` --label ${ccName} ` + + ` --lang golang`; + + const ccPkgLabel = `packaging chain code`; + const ccPkgRes = await sshExec(ctx, ccPkgCmd, ccPkgLabel, ssh, sshOpts); + Checks.truthy(ccPkgRes.code === 0, `ccPkgRes.code === 0`); + + for (const org of req.targetOrganizations) { + const dockerExecEnv = Object.entries(org) + .map(([key, val]) => `--env ${key}=${val}`) + .join(" "); + + const dockerExecCmd = + `${dockerBinary} exec ` + + dockerExecEnv + + ` --env GO111MODULE=on` + + ` --workdir=${remoteDirPath}` + + ` cli `; + + const ccInstallLbl = `Install ChainCode in ${org.CORE_PEER_LOCALMSPID}`; + const ccInstallCmd = `${dockerExecCmd} peer lifecycle chaincode install ${ccName}.tar.gz `; + + const anInstallCmdRes = await sshExec( + ctx, + ccInstallCmd, + ccInstallLbl, + ssh, + sshOpts, + ); + + installationCommandResponses.push(anInstallCmdRes); + + // const ctorArgsJson = JSON.stringify(req.constructorArgs || {}); + + // Need to make sure that the logging is turned off otherwise it + // mangles the JSON syntax and makes the output invalid... + const dockerExecCmdInfoLog = findAndReplaceFabricLoggingSpec( + dockerExecCmd, + "ERROR", + ); + + const instantiationCommandResponses = []; + const cmdQueryInstalled = `${dockerExecCmdInfoLog} peer lifecycle chaincode queryinstalled --output json`; + const lblQueryInstalled = `query installed contracts`; + const resQueryInstalled = await sshExec( + ctx, + cmdQueryInstalled, + lblQueryInstalled, + ssh, + sshOpts, + ); + + log.debug("Queries installed contracts OK."); + Checks.truthy(resQueryInstalled.stdout.includes(ccName)); + log.debug("Validated that contract is in fact installed OK."); + + const json = resQueryInstalled.stdout; + const qir = JSON.parse(json) as IQueryInstalledResponse; + const icc = qir.installed_chaincodes.find( + (chainCode) => chainCode.label === ccName, + ); + + ctx.log.debug(`Parsed list of installed contracts: %o`, qir); + + Checks.truthy(icc, "No installed chaincode with label: %o", ccName); + + if (!icc?.package_id) { + throw new Error(`${fnTag}: package ID falsy. Something's wrong.`); + } + const packageId = icc?.package_id; + ctx.log.debug(`Found package ID: ${packageId}`); + + const instantiateCmd = + ` ${dockerExecCmd} peer lifecycle chaincode approveformyorg ` + + `--orderer ${orderer} ` + + `--ordererTLSHostnameOverride ${ordererTLSHostnameOverride} ` + + `--tls ` + + `--cafile ${FABRIC_25_LTS_FABRIC_SAMPLES__ORDERER_TLS_ROOTCERT_FILE_ORG_1} ` + + `--channelID ${req.channelId} ` + + `--name ${ccName} ` + + `--version ${req.chainCodeVersion} ` + + `--package-id ${packageId} ` + + `--sequence ${ccSequence} ` + + ``; + + const cmdLabel = `approveformyorg ChainCode in ${org.CORE_PEER_LOCALMSPID}`; + log.debug(`ApproveForMyOrg CMD: %o`, instantiateCmd); + + const instantiationCmdRes = await sshExec( + ctx, + instantiateCmd, + cmdLabel, + ssh, + sshOpts, + ); + Checks.truthy(instantiationCmdRes.code === 0, `res.code === 0`); + instantiationCommandResponses.push(instantiationCmdRes); + + log.debug(`ApproveForMyOrg CMD Response:%o`, instantiationCmdRes); + success = success && isSshExecOk(instantiationCmdRes); + } + + const commitCmd = + `${dockerBuildCmd} peer lifecycle chaincode commit ` + + ` --name ${ccName} ` + + ` --version ${req.chainCodeVersion} ` + + ` --channelID ${req.channelId} ` + + ` --tls ` + + ` --orderer ${orderer} ` + + ` --ordererTLSHostnameOverride ${ordererTLSHostnameOverride} ` + + ` --cafile ${FABRIC_25_LTS_FABRIC_SAMPLES__ORDERER_TLS_ROOTCERT_FILE_ORG_1} ` + + ` --peerAddresses ${req.targetOrganizations[0].CORE_PEER_ADDRESS} ` + + ` --tlsRootCertFiles ${req.targetOrganizations[0].CORE_PEER_TLS_ROOTCERT_FILE}` + + ` --peerAddresses ${req.targetOrganizations[1].CORE_PEER_ADDRESS} ` + + ` --tlsRootCertFiles ${req.targetOrganizations[1].CORE_PEER_TLS_ROOTCERT_FILE}` + + ` --sequence=${ccSequence} `; + + const lblCcCommit = "peer lifecycle chaincode commit"; + + const resCommit = await sshExec(ctx, commitCmd, lblCcCommit, ssh, sshOpts); + + success = success && isSshExecOk(resCommit); + + // Need to make sure that the logging is turned off otherwise it + // mangles the JSON syntax and makes the output invalid... + const dockerBuildCmdInfoLog = findAndReplaceFabricLoggingSpec( + dockerBuildCmd, + "ERROR", + ); + + const cmdQueryCommitted2 = `${dockerBuildCmdInfoLog} peer lifecycle chaincode querycommitted --channelID=${req.channelId} --output json`; + const lblQueryCommitted2 = `peer lifecycle chaincode querycommitted --channelID=${req.channelId}`; + + log.debug(`${lblQueryCommitted2} CMD Response:%o`, cmdQueryCommitted2); + + const resQueryCommitted2 = await sshExec( + ctx, + cmdQueryCommitted2, + lblQueryCommitted2, + ssh, + sshOpts, + ); + + Checks.truthy( + resQueryCommitted2.stdout.includes(ccName), + "stdout has contract name", + ); + const committedCCsJson = resQueryCommitted2.stdout; + const qcr2 = JSON.parse(committedCCsJson) as IQueryCommittedResponse; + const ccd2 = qcr2.chaincode_definitions.find( + (ccd) => ccd.name === ccName && ccd.version === req.chainCodeVersion, + ); + + ctx.log.debug(`Parsed list of installed contracts: %o`, qcr2); + + Checks.truthy(ccd2, "No installed chaincode with label: %o", ccName); + + log.debug(`EXIT doDeploy()`); + const res: DeployContractGoSourceV1Response = { + success, + installationCommandResponses, + instantiationCommandResponse: installationCommandResponses[0], + }; + + return res; + } catch (ex) { + ctx.log.debug(`${fnTag} crashed. Re-throwing...`, ex); + throw ex; + } finally { + try { + ssh.dispose(); + } finally { + temp.cleanup(); + } + } +} diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts index 4dac5a77bf..6302c3ad85 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts @@ -141,6 +141,8 @@ import { GetBlockEndpointV1 } from "./get-block/get-block-endpoint-v1"; import { querySystemChainCode } from "./common/query-system-chain-code"; import { isSshExecOk } from "./common/is-ssh-exec-ok"; import { asBuffer, assertFabricFunctionIsAvailable } from "./common/utils"; +import { findAndReplaceFabricLoggingSpec } from "./common/find-and-replace-fabric-logging-spec"; +import { deployContractGoSourceImplFabricV256 } from "./deploy-contract-go-source/deploy-contract-go-source-impl-fabric-v2-5-6"; const { loadFromConfig } = require("fabric-network/lib/impl/ccp/networkconfig"); assertFabricFunctionIsAvailable(loadFromConfig, "loadFromConfig"); @@ -392,7 +394,7 @@ export class PluginLedgerConnectorFabric } temp.track(); - const tmpDirPrefix = `hyperledger-cactus-${this.className}`; + const tmpDirPrefix = `hyperledger-cacti-${this.className}`; const tmpDirPath = temp.mkdirSync(tmpDirPrefix); const remoteDirPath = path.join(this.cliContainerGoPath, "src/", ccLabel); @@ -429,31 +431,12 @@ export class PluginLedgerConnectorFabric ` --workdir=${remoteDirPath}` + ` cli `; - const r1 = new RegExp( - `\\s+(-e|--env)\\s+CORE_LOGGING_LEVEL='?"?\\w+'?"?\\s+`, - "gmi", - ); - const r2 = new RegExp(`FABRIC_LOGGING_SPEC=('?"?\\w+'?"?)`, "gmi"); - // Need to make sure that the logging is turned off otherwise it // mangles the JSON syntax and makes the output invalid... - const dockerBuildCmdInfoLog = dockerBuildCmd - .replace(r1, " ") - .replace(r2, " FABRIC_LOGGING_SPEC=ERROR "); - - // await this.sshExec( - // `${dockerBinary} exec cli mkdir -p ${remoteDirPath}/`, - // "Create ChainCode project (go module) directory", - // ssh, - // sshCmdOptions, - // ); - - // await this.sshExec( - // `${dockerBinary} exec cli go version`, - // "Print go version", - // ssh, - // sshCmdOptions, - // ); + const dockerBuildCmdInfoLog = findAndReplaceFabricLoggingSpec( + dockerBuildCmd, + "ERROR", + ); for (const sourceFile of sourceFiles) { const { filename, filepath, body } = sourceFile; @@ -469,13 +452,6 @@ export class PluginLedgerConnectorFabric log.debug(`SCP OK %o`, remoteDirPath); if (ccLang === ChainCodeProgrammingLanguage.Golang) { - // const cliRemoteDirPath = path.join(remoteDirPath, "../"); - // const copyToCliCmd = `${dockerBinary} cp ${remoteDirPath} cli:${cliRemoteDirPath}`; - // log.debug(`Copy to CLI Container CMD: ${copyToCliCmd}`); - // const copyToCliRes = await ssh.execCommand(copyToCliCmd, sshCmdOptions); - // log.debug(`Copy to CLI Container CMD Response: %o`, copyToCliRes); - // Checks.truthy(copyToCliRes.code === null, `copyToCliRes.code === null`); - { const label = "docker copy go code to cli container"; const cliRemoteDirPath = path.join(remoteDirPath, "../"); @@ -670,191 +646,14 @@ export class PluginLedgerConnectorFabric public async deployContractGoSourceV1( req: DeployContractGoSourceV1Request, ): Promise { - const fnTag = `${this.className}#deployContract()`; const { log } = this; - - const ssh = new NodeSSH(); - await ssh.connect(this.opts.sshConfig); - log.debug(`SSH connection OK`); - - try { - log.debug(`${fnTag} Deploying .go source: ${req.goSource.filename}`); - - Checks.truthy(req.goSource, `${fnTag}:req.goSource`); - - temp.track(); - const tmpDirPrefix = `hyperledger-cactus-${this.className}`; - const tmpDirPath = temp.mkdirSync(tmpDirPrefix); - - // The module name of the chain-code, for example this will extract - // ccName to be "hello-world" from a filename of "hello-world.go" - const inferredModuleName = path.basename(req.goSource.filename, ".go"); - log.debug(`Inferred module name: ${inferredModuleName}`); - const ccName = req.moduleName || inferredModuleName; - log.debug(`Determined ChainCode name: ${ccName}`); - - const remoteDirPath = path.join(this.cliContainerGoPath, "src/", ccName); - log.debug(`Remote dir path on CLI container: ${remoteDirPath}`); - - const localFilePath = path.join(tmpDirPath, req.goSource.filename); - fs.writeFileSync(localFilePath, req.goSource.body, "base64"); - - const remoteFilePath = path.join(remoteDirPath, req.goSource.filename); - - log.debug(`SCP from/to %o => %o`, localFilePath, remoteFilePath); - await ssh.putFile(localFilePath, remoteFilePath); - log.debug(`SCP OK %o`, remoteFilePath); - - const sshCmdOptions: SSHExecCommandOptions = { - execOptions: { - pty: true, - env: { - // just in case go modules would be otherwise disabled - GO111MODULE: "on", - FABRIC_LOGGING_SPEC: "DEBUG", - }, - }, - cwd: remoteDirPath, - }; - - const dockerExecEnv = Object.entries(this.opts.cliContainerEnv) - .map(([key, value]) => `--env ${key}=${value}`) - .join(" "); - - const { dockerBinary } = this; - const dockerBuildCmd = - `${dockerBinary} exec ` + - dockerExecEnv + - ` --env GO111MODULE=on` + - ` --workdir=${remoteDirPath}` + - ` cli `; - - await this.sshExec( - `${dockerBinary} exec cli mkdir -p ${remoteDirPath}/`, - "Create ChainCode project (go module) directory", - ssh, - sshCmdOptions, - ); - - await this.sshExec( - `${dockerBinary} exec cli go version`, - "Print go version", - ssh, - sshCmdOptions, - ); - - const copyToCliCmd = `${dockerBinary} cp ${remoteFilePath} cli:${remoteFilePath}`; - log.debug(`Copy to CLI Container CMD: ${copyToCliCmd}`); - const copyToCliRes = await ssh.execCommand(copyToCliCmd, sshCmdOptions); - log.debug(`Copy to CLI Container CMD Response: %o`, copyToCliRes); - Checks.truthy(copyToCliRes.code === 0, `copyToCliRes.code === 0`); - - { - const goModInitCmd = `${dockerBuildCmd} go mod init ${ccName}`; - log.debug(`go mod init CMD: ${goModInitCmd}`); - const goModInitRes = await ssh.execCommand(goModInitCmd, sshCmdOptions); - log.debug(`go mod init CMD Response: %o`, goModInitRes); - Checks.truthy(goModInitRes.code === 0, `goModInitRes.code === 0`); - } - - const pinnedDeps = req.pinnedDeps || []; - for (const dep of pinnedDeps) { - const goGetCmd = `${dockerBuildCmd} go get ${dep}`; - log.debug(`go get CMD: ${goGetCmd}`); - const goGetRes = await ssh.execCommand(goGetCmd, sshCmdOptions); - log.debug(`go get CMD Response: %o`, goGetRes); - Checks.truthy(goGetRes.code === 0, `goGetRes.code === 0`); - } - - { - const goModTidyCmd = `${dockerBuildCmd} go mod tidy`; - log.debug(`go mod tidy CMD: ${goModTidyCmd}`); - const goModTidyRes = await ssh.execCommand(goModTidyCmd, sshCmdOptions); - log.debug(`go mod tidy CMD Response: %o`, goModTidyRes); - Checks.truthy(goModTidyRes.code === 0, `goModTidyRes.code === 0`); - } - - { - const goVendorCmd = `${dockerBuildCmd} go mod vendor`; - log.debug(`go mod vendor CMD: ${goVendorCmd}`); - const goVendorRes = await ssh.execCommand(goVendorCmd, sshCmdOptions); - log.debug(`go mod vendor CMD Response: %o`, goVendorRes); - Checks.truthy(goVendorRes.code === 0, `goVendorRes.code === 0`); - } - - { - const goBuildCmd = `${dockerBuildCmd} go build`; - log.debug(`go build CMD: ${goBuildCmd}`); - const goBuildRes = await ssh.execCommand(goBuildCmd, sshCmdOptions); - log.debug(`go build CMD Response: %o`, goBuildRes); - Checks.truthy(goBuildRes.code === 0, `goBuildRes.code === 0`); - } - - const installationCommandResponses: SSHExecCommandResponse[] = []; - // https://github.com/hyperledger/fabric-samples/blob/release-1.4/fabcar/startFabric.sh - for (const org of req.targetOrganizations) { - const env = - ` --env CORE_PEER_LOCALMSPID=${org.CORE_PEER_LOCALMSPID}` + - ` --env CORE_PEER_ADDRESS=${org.CORE_PEER_ADDRESS}` + - ` --env CORE_PEER_MSPCONFIGPATH=${org.CORE_PEER_MSPCONFIGPATH}` + - ` --env CORE_PEER_TLS_ROOTCERT_FILE=${org.CORE_PEER_TLS_ROOTCERT_FILE}`; - - const anInstallationCommandResponse = await this.sshExec( - dockerBinary + - ` exec ${env} cli peer chaincode install` + - ` --name ${ccName} ` + - ` --path ${ccName} ` + - ` --version ${req.chainCodeVersion} ` + - ` --lang golang`, - `Install ChainCode in ${org.CORE_PEER_LOCALMSPID}`, - ssh, - sshCmdOptions, - ); - - installationCommandResponses.push(anInstallationCommandResponse); - } - - let success = true; - - const ctorArgsJson = JSON.stringify(req.constructorArgs || {}); - const ordererCaFile = - "/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"; - - const instantiateCmd = - `${dockerBuildCmd} peer chaincode instantiate ` + - ` --name ${ccName} ` + - ` --version ${req.chainCodeVersion} ` + - ` --ctor '${ctorArgsJson}' ` + - ` --channelID ${req.channelId} ` + - ` --peerAddresses ${req.targetPeerAddresses[0]} ` + - ` --lang golang ` + - ` --tlsRootCertFiles ${req.tlsRootCertFiles}` + - ` --policy "${req.policyDslSource}"` + - ` --tls --cafile ${ordererCaFile}`; - - log.debug(`Instantiate CMD: %o`, instantiateCmd); - const instantiationCommandResponse = await ssh.execCommand( - instantiateCmd, - sshCmdOptions, - ); - - log.debug(`Instantiate CMD Response:%o`, instantiationCommandResponse); - success = success && isSshExecOk(instantiationCommandResponse); - - log.debug(`EXIT doDeploy()`); - const res: DeployContractGoSourceV1Response = { - success, - installationCommandResponses, - instantiationCommandResponse, - }; - return res; - } finally { - try { - ssh.dispose(); - } finally { - temp.cleanup(); - } - } + const ctx = { + log, + opts: this.opts, + dockerBinary: this.dockerBinary, + className: this.className, + }; + return deployContractGoSourceImplFabricV256(ctx, req); } /**