Error building chaincode written in go - go

When I try to modify the example described in this hyperledger example I get some error when adding this external library in order to get the History of the chaincode state.
Why does that happen?
I add the library with govendor, but when I run this command:
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin#org1.example.com/msp" cli peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n $CC_NAME -l "$LANGUAGE" -v 1.0 -c $INIT_STR -P "OR ('Org1MSP.member','Org2MSP.member')"
I get this error:
Error: Error endorsing chaincode:
rpc error: code = Unknown desc = error starting container: Failed to generate platform-specific docker build: Error returned from build: 2 "# firstExample
chaincode/input/src/firstExample/firstStep.go:104:11: cannot assign *"github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification to kM (type *"firstExample/vendor/github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification) in multiple assignment
chaincode/input/src/firstExample/firstStep.go:146:11: cannot assign *"github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification to kM (type *"firstExample/vendor/github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification) in multiple assignment
chaincode/input/src/firstExample/firstStep.go:156:11: cannot assign *"github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification to kM (type *"firstExample/vendor/github.com/hyperledger/fabric/protos/ledger/queryresult".KeyModification) in multiple assignment
I have some troubles with this. I'm sure that the library is imported because if I build the chaincode written in go with the command:
go build
I get no errors.
Please help me!

It's very hard to guess without seeing actual code which cause the compilation error, while it seems that you are not taking care of the second parameter which returned by HistoryQueryIteratorInterface#Next() API or even ChaincodeStubInterface#GetHistoryForKey(). Please see example of how to use those APIs correctly:
// GetPreviousValue reads previous value of given key
func (pm *personManagement) GetPreviousValue(params []string, stub shim.ChaincodeStubInterface) peer.Response {
historyIer, err := stub.GetHistoryForKey(params[0])
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot retrieve history of key <%s>, due to %s", params[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
if historyIer.HasNext() {
modification, err := historyIer.Next()
if err != nil {
errMsg := fmt.Sprintf("[ERROR] cannot read key record modification, key <%s>, due to %s", params[0], err)
fmt.Println(errMsg)
return shim.Error(errMsg)
}
fmt.Println("Returning information about", string(modification.Value))
return shim.Success(modification.Value)
}
fmt.Printf("No history found for key %s\n", params[0])
return shim.Success([]byte(fmt.Sprintf("No history for key %s", params[0])))
}
NOTE: Please pay attention that historyIer.Next() returns history value and the error.

Related

Unable to start shell: Failed to start pty: fork/exec /usr/bin/sh: operation not permitted

I'm trying to install and run AWS SSM Agent under non-root user on on-premise environment. For example, I brought up the amazon-ssm-agent process as ec2-user on OS. No problem with the registration and I could see the Ping status as 'online' in AWS SSM console. However, when I tried to start session against the instance through session manager, it always failed and prompts error like this:
"Output": "\n----------ERROR-------\nUnable to start shell: Failed to start pty: fork/exec /usr/bin/sh: operation not permitted
And the related source code snippet is this:
func StartPty(
log log.T,
shellProps mgsContracts.ShellProperties,
isSessionLogger bool,
config agentContracts.Configuration,
plugin *ShellPlugin) (err error) {
log.Info("Starting pty")
//Start the command with a pty
var cmd *exec.Cmd
if strings.TrimSpace(shellProps.Linux.Commands) == "" || isSessionLogger {
cmd = exec.Command("sh")
} else {
commandArgs := append(utility.ShellPluginCommandArgs, shellProps.Linux.Commands)
cmd = exec.Command("date", commandArgs...)
}
....
ptyFile, err = pty.Start(cmd)
if err != nil {
log.Errorf("Failed to start pty: %s\n", err)
return fmt.Errorf("Failed to start pty: %s\n", err)
}
Initially I though maybe it's permission issue with that shell binary file. But there's nothing wrong with that and everybody could run the shell command.
Does anybody know what's going on here and have any advice on how to figure it out? thanks
Btw, AWS SSM agent source code is based on Go programming language.

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed Error ID: 6191efcd

I am getting the following error since this morning but nothing changed regarding my code (just added a log.println()... Even getting back to a previous version that was deployed doesn't solve the issue)
trigger.go (entry point)
// The function that runs with the cloud function itself
func HandleUserCreateEvent(ctx context.Context, e my_project.FirestoreEvent) error {
log.Println("-------------------- oldValue --------------------")
log.Printf("Name: %s\n", e.OldValue.Name)
log.Printf("CreateTime: %v\n", e.OldValue.CreateTime)
log.Printf("Fields: %v\n", e.OldValue.Fields)
log.Printf("UpdateTime: %v\n", e.OldValue.UpdateTime)
log.Println("-------------------- newValue --------------------")
log.Printf("Name: %s\n", e.Value.Name)
log.Printf("CreateTime: %v\n", e.Value.CreateTime)
log.Printf("Fields: %v\n", e.Value.Fields)
log.Printf("UpdateTime: %v\n", e.Value.UpdateTime)
log.Println("-------------------- jsonValue -------------------")
jsonB, _ := json.Marshal(e.Value)
log.Printf("Json: %v\n", string(jsonB))
log.Println("---------------------- DONE ----------------------")
// My code
return nil
deploy.sh (having also a deploy.bat which was working as well as the sh script below)
#!/usr/bin/env bash
# Deployment automation
name="HandleUserCreateEvent"
projectId="my_project"
collection="UsersCollection"
# Must call go vendor as go modules are ignored
go mod vendor
yes Y | gcloud functions deploy ${name} \
--trigger-event providers/cloud.firestore/eventTypes/document.create \
--trigger-resource "projects/${projectId}/databases/(default)/documents/${collection}/{pushId}" \
--region europe-west1 \
--runtime go113 \
--allow-unauthenticated \
--memory 128
As this was working perfectly, now it doesn't anymore (as stated, I just added the jsonValue part of the code you see above)
Error
MacBook-Pro-de-Emixam23:my-project-elasticsearch-creater emixam23$ ./deploy.sh
Deploying function (may take a while - up to 2 minutes)...
....................................................failed.
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: # serverless_function_app/main
src/serverless_function_app/main/main.go:24:38: cannot use my_project_elasticsearch_creater.HandleUserCreateEvent (type func(context.Context, my_project_elasticsearch.FirestoreEvent) error) as type func(http.ResponseWriter, *http.Request) in argument to funcframework.RegisterHTTPFunction; Error ID: 6191efcd
Any idea? I really think that gcloud has some issues...
Update -> gcloud is really broken
I just redeployed an empty function, with only a simple struct as package with no dependencies (go modules empty)
type FirestoreEvent struct {
OldValue interface{} `json:"oldValue"`
Value interface{} `json:"value"`
UpdateMask struct {
FieldPaths []string `json:"fieldPaths"`
} `json:"updateMask"`
}
Still the same issue
C:\Workspace\go\src\gitlab-group\my-project-elasticsearch-creater>gcloud --version
Google Cloud SDK 298.0.0
app-engine-go
app-engine-python 1.9.91
bq 2.0.58
cloud-datastore-emulator 2.1.0
core 2020.06.19
gsutil 4.51
I tried the exact same at the end of the same day and it worked...
I believe it was a Google Cloud Platform issue related, no idea why we were not able to deploy it during a couple of hours.

ERR wrong number of arguments for 'zadd' command

I have found this Error:
ERR wrong number of arguments for 'zadd' command in golang.
This is my code:
defaultPriority:type String
mb.MessageID:type string
mb.EndpointID: type string
_, err = mbDal.redisClient.ZAdd(mb.EndpointID, redis.Z{Score: defaultPriority, Member: mb.MessageID})
if err != nil {
return fmt.Errorf("failed to add mailbox id %s in redis; error %v", mb.MessageID, err)
}
How can I fix this error message?
zadd is used in go-redis/redis, and is defined here
// Redis `ZADD key score member [score member ...]` command.
func (c cmdable) ZAdd(key string, members ...*Z) *IntCmd {
Double-check your go.mod dependencies list.
10 months ago, in go-redis v7 (instead of current v8), the signature for that function was:
func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {
It used Z instead of (today) *Z.
In your case, you should pass:
&redis.Z{Score: defaultPriority, Member: mb.MessageID}
I was trying to insert redis.Z{Score: [an int value], Member: code} to Redis sorted set and it failed with that error.
So I checked my logic and find out someone calling my method with code as an empty string. in my case first insert was successful but after that, all insert failed with that error.
I'm using github.com/go-redis/redis v6.15.6

Proper way to get errno value out of PathError

I'm trying to determine whether an os.PathError is due to an EINVAL or ENOENT. How do I correctly make that determination?
res, err := os.Readlink(fpath)
if err, ok := err.(*os.PathError); ok {
if err.Err == os.ErrInvalid {
// This path here. What's the correct check?
return fpath
}
log.Printf("ResolveLinks error: %s", err)
return ""
}
log.Printf("Resolved: %s to %s", fpath, res)
return res
If fpath points to a regular file instead of a symlink, readlink should produce EINVAL, but my err.Err == os.ErrInvalid check fails and the following is logged:
2019/03/28 12:04:42 ResolveLinks error: readlink foo: invalid argument
I'm supposed to unpack the PathError, but then what? Compare the error string?
I notice that the os module has certain functions to match error types, like os.IsNotExist, but I don't see one for all possible error codes.
The err.Err is of type syscall.Errno and this is integer type that you can convert to int. Running this code on Ubuntu produces error code 22:
if serr, ok := err.Err.(syscall.Errno); ok {
fmt.Println(int(serr))
}
Bear in mind I do not know if this kind of check is cross platform or not.
if you just want to check file is symlink you can use Lstat to get FileInfo struct and do the check:
fi.Mode() & os.ModeSymlink != 0
I've found that the error's string will allow to match on the error type, but I'm not confident (at all) this works across platforms or even locales.
if err, ok := err.(*os.PathError); ok {
//EINVAL
if err.Err.Error() == "invalid argument" {
…
// - OR -
//ENOENT
if err.Err.Error() == "no such file or directory" {
…
}

Save error in database Golang

I'm running http request in golang
resp, err := client.Do(req)
if err != nil {
return "", err
}
So, it returns error back to the main function, that attempts to store it in the database:
_, err = db.Exec("UPDATE test SET error = $1 WHERE id = $2", error, id)
I receive the following error: sql: converting Exec argument #1's type: unsupported type errors.errorString, a struct exit status 1
So, I understand, that error has a different type, but I can't find information on how to pass the value of the error to the string. Could someone direct me in a right way.
Use the function:
error.Error()
to get a string representation of the error.
Tip: avoid naming variables with existing type names. error is a type name and it's also your variable name, which might lead to confusion.

Resources