Reputation: 5415
I have the following setup, and I am trying to create a multi-function GCP Cloud Function project, but I am failing to deploy any functions because of a "generic" error which is not very helpful at all.
My project structure looks like this, to keep things simple I only write out function1, but there is a function2, etc.
Using Cloud Functions go 1.13
support and go mod
support
Project structure:
.
├── go.mod
├── function1
│ └── function1.go
├── common
│ └── common.go // Contains struct GCSEvent see https://cloud.google.com/functions/docs/calling/storage#functions-calling-storage-go
└── main.go
Code snippets:
// go.mod
module github.com/me/myproject
go 1.13
// function1/function1.go
package function1
import (
"github.com/me/myproject/common"
// Other imports
)
func Function1(ctx context.Context, gcsEvent common.GCSEvent) error {
// Do Stuff
}
// common/common.go
package common
// See https://cloud.google.com/functions/docs/calling/storage#functions-calling-storage-go
type GCSEvent struct {
// ...
}
// main.go
package main
import (
"github.com/me/myproject/function1"
"github.com/me/myproject/common"
"context"
// Other imports
)
func main() {
// Call Function1 from the command line for manual testing
event := common.GCSEvent{/*...*/}
function1.Function1(context.Background(), event)
}
function1.go
references common.go
using the go module import syntax which GCP should be able to resolve.
To deploy the function I call gcloud, from the root directory of the project:
gcloud functions deploy Function1 --runtime=go113 <more arguments...>
And the error I receive is
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Build error details not available
Which I mentioned is not very helpful at all.
Upvotes: 0
Views: 2102
Reputation: 5415
To solve the first error
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Build error details not available
I had to realize that Cloud Functions can only(?) be deployed from the root directory of the project, but my Cloud Function was in the subpackage function1/
To solve this I created a Proxy function in a new file functions.go
in the root of the project.
// functions.go DO NOT USE SEE BELOW
// functions.go DO NOT USE SEE BELOW
// functions.go DO NOT USE SEE BELOW
package main // Please note that this package is _wrong_ which will become clear further down in the answer
import (
"github.com/me/myproject/function1"
"github.com/me/myproject/common"
"context"
)
// Proxy function to the real Function1 in package function1
func Function1(ctx context.Context, gcsEvent common.GCSEvent) error {
return backupdelegate.Function1(ctx, gcsEvent)
}
Deploying this seemed successful, until I got a new error message, a bit less confusing but still confusing:
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: go: downloading github.com/GoogleCloudPlatform/functions-framework-go v0.3.0
I checked my go.mod
and go.sum
but they did not contain any references to functions-framework-go
. It was something GCP was downloading "for me", instead of just telling me what I was doing wrong.
It wasn't until I read the description of GoogleCloudPlatform/functions-framework-go that I realized that it probably had something to do with the main function of my code.
After testing a few things I came to the conclusion that:
main
.
├── go.mod
├── function1
│ └── function1.go
├── common
│ └── common.go
├── testing
│ └── main.go
└── functions.go
// functions.go
// THIS IS THE CORRECT VERSION OF THE PROXY FUNCTION(S)
package functions
import (
"github.com/me/myproject/function1"
"github.com/me/myproject/common"
"context"
)
// Proxy function to the real Function1 in package function1
func Function1(ctx context.Context, gcsEvent common.GCSEvent) error {
return backupdelegate.Function1(ctx, gcsEvent)
}
As you can see from the project structure I had to move main.go
into a subfolder because go only allows one package per folder.
After these last changes the functions deployed successfully.
This answer helped me with structuring the subpackages, go give it some love: How can I use a sub-packages with Go on Google Cloud Functions?
As a last note I would like to throw some shade on the GCP Cloud Functions documentation which lacks some advanced examples and does not make it extremely clear about package naming, placement of functions, and so on - at least for Go projects.
Upvotes: 4