fastly / Viceroy

Viceroy provides local testing for developers working with Compute.
https://fastly.dev/learning/compute/testing/#running-a-local-testing-server
Apache License 2.0
142 stars 35 forks source link

Golang programs that import flag or httptest will panic due to uninitialized os.Args #376

Closed StevenACoffman closed 2 days ago

StevenACoffman commented 1 month ago

When I try to run fastly compute serve with webassembly code that I build with GOARCH=wasm GOOS=wasip1 go build ./... if I have code that even indirectly includes flag then the flag package imports httptest ( _ "net/http/httptest") which will panic when it gets to: https://github.com/golang/go/blob/3ed007d754b685cd8f6011a8e96a3c9303c785db/src/flag/flag.go#L1199

An example piece of code

package main

import (
    "fmt"
    "os"

    _ "bytes"
    _ "context"
    _ "encoding/json"
    _ "net"
    _ "net/http"

    // This causes issues!
    _ "net/http/httptest"

    _ "net/url"
    _ "strconv"
    _ "strings"
)

func main() {
    fmt.Println("FASTLY_SERVICE_VERSION:", os.Getenv("FASTLY_SERVICE_VERSION"))
}

and run fastly compute serve with this fastly.toml file:

# This file describes a Fastly Compute package. To learn more visit:
# https://www.fastly.com/documentation/reference/compute/fastly-toml

authors = ["XXXXacademy.org"]
cloned_from = "https://github.com/fastly/compute-starter-kit-go-default"
description = "fastly compute go service"
language = "go"
manifest_version = 3
name = "fastly-khanacademy-compute"
service_id = "XXXX"

[scripts]
  build = "go build -o bin/main.wasm ./cmd/serve"
  env_vars = ["GOARCH=wasm", "GOOS=wasip1"]
  post_init = "go get github.com/fastly/compute-sdk-go@latest"

# Despite most of the local_server configuration being in the fastly.{env}.toml
# files, this actually needs to be defined in our basic fastly.toml file.
# It MUST be defined as the full semantic version, but without the 'v'.
# The 'fastly' cli must be at version 10.2.0 or later to use this.
[local_server]
  viceroy_version = "0.9.6"

I can reproduce this problem with tinygo, but wasmtime doesn't seem to have the problem directly, so I assume it is a viceroy problem.

I mentioned this in the gophers slack and @dgryski said he passed it on to a colleague, but I didn't want others to duplicate bug reports, so I thought I'd record it here for others to track.

kpfleming commented 1 month ago

Could you try with 0.9.7? It has a newer wasmtime, it's possible there may be some interaction there.

dgryski commented 1 month ago

This still happens with viceroy 0.9.7.

A much smaller reproducer is:

package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Println(os.Args[0])
}
ydnar commented 1 month ago

Would it be reasonable to supply at least one WASI arg to the guest? Either with some default value like wasm, or the name of the service?

dgryski commented 1 month ago

@ydnar Yes. The baseame of the wasm file I believe is accessible; worst case we just lie.

StevenACoffman commented 3 weeks ago

@ydnar Do you have a pointer for where this could be plumbed through? I'm not much of a rustacean.