"No such file or directory" on Google Cloud Function using Go 1.13

Viewed 988

I have a Google Cloud Function written in Go and deployed using Go 1.11 runtime, and it works. The problem arises when upgrading the runtime to Go 1.13, the same function and I get this error:

Error: could not handle the request

and in the logs of the Cloud Function I have these details of the error:

Function execution started
open ./progress.html: no such file or directory
Function execution took 232 ms, finished with status: 'connection error'

The file is there, in the same folder as the Go file.

Here is the relevant code of the function:

// Progress ... Entrypoint of our Cloud Function
func Progress(w http.ResponseWriter, r *http.Request) {
        
        ...

        tpl, err := template.ParseFiles("progress.html")
        if err != nil {
            log.Fatalln(err)
        }

        buf := new(bytes.Buffer)

        err = tpl.Execute(buf, data)
        if err != nil {
            log.Fatalln(err)
        }
       ...
    }

And if it helps, here is the repository of this function.

The only thing that changes is the Go runtime used for deploying it, from 1.11 to 1.13.

Here are the two commands used for deploying it:

It works:

gcloud functions deploy progress --runtime go111 --entry-point Progress --trigger-http --memory 128MB

It doesn't work (it deploys successfully, but the error appears when using the function):

gcloud functions deploy progress --runtime go113 --entry-point Progress --trigger-http --memory 128MB
1 Answers

The error was assuming that the Google Cloud Functions using different runtimes were implemented the same, but debugging, I was able to find some differences.

Here is a test function to debug it:

func Progress(w http.ResponseWriter, r *http.Request) {
    wd, _ := os.Getwd()
    fmt.Fprintf(w, "$> pwd\n%s\n\n", wd)
  
    bytes, _ = exec.Command("ls", "-l").CombinedOutput()
    fmt.Fprintf(w, "$> ls -l\n%s\n\n", bytes)
}

Here is the output using Go 1.11 runtime:

$> pwd
/srv/files/

$> ls -l
total 5
-rw-r--r-- 1 root root 1068 Aug 13 04:15 LICENSE
-rw-r--r-- 1 root root 1097 Aug 13 04:15 README.md
drwxr-xr-x 2 root root    0 Aug 13 04:15 colors-example
-rw-r--r-- 1 root root 2093 Aug 13 04:15 progress.go
-rw-r--r-- 1 root root  627 Aug 13 04:15 progress.html

As you can see, all the files are in the current directory, including the missing file progress.html.

But here is the output when using Go 1.13 runtime:

$> pwd
/srv

$> ls -l
total 0
drwxr-xr-x 2 www-data www-data 0 Jan  1  1980 pkg
drwxr-xr-x 2 www-data www-data 0 Jan  1  1980 src

Notice how my files are no longer there, so I printed the content of src and contained a folder called progress (the name of my project).

Inside that folder, there were all my files.

So the fix when using the Go 1.13 runtime was:

// Progress ... Entrypoint of our Cloud Function
func Progress(w http.ResponseWriter, r *http.Request) {
        
        ...

        tpl, err := template.ParseFiles("src/progress/progress.html")
        if err != nil {
            log.Fatalln(err)
        }

        buf := new(bytes.Buffer)

        err = tpl.Execute(buf, data)
        if err != nil {
            log.Fatalln(err)
        }
       ...
    }

I hope it helps somebody, not only for the answer but also if the rules change for new runtimes, you have a way to debug it and find the right location of your files.

Related