-
Notifications
You must be signed in to change notification settings - Fork 7
compile error --this SDK has been moved to https://github.com/open-policy-agent/opa/tree/main/internal/wasm/sdk #9
Description
Describe the bug
A compile bug related with opa.OPA struct initialization.
A clear and concise description of what the bug is
I tried to use this SDK to realize a simple policy center but to find a very strange compile error:
/usr/local/Cellar/go/1.16.5/libexec/pkg/tool/darwin_amd64/link:
running clang failed: exit status 1 Undefined symbols for architecture x86_64:
"_wasi_config_arg", referenced from:
__cgo_cbbfd67d0eb3_Cfunc_wasi_config_arg in 000042.o
(maybe you meant: __cgo_cbbfd67d0eb3_Cfunc_wasi_config_arg)
"_wasi_config_capture_stderr", referenced from:
__cgo_cbbfd67d0eb3_Cfunc_wasi_config_capture_stderr in 000042.o
(maybe you meant: __cgo_cbbfd67d0eb3_Cfunc_wasi_config_capture_stderr)
... errors like the above...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
After debug I found this error is related with the reference of opa.OPA in different packages. However, I failed to reproduce this error in a new project.
Steps to reproduce
The following code is probably the codes that trigger the error.
I wrote the policycenter.go to realize a rules:
package policycenter
import (
"context"
"encoding/json"
"fmt"
"github.com/open-policy-agent/golang-opa-wasm/opa"
)
type PolicyCenter interface {
Eval(entity *PolicyEntity, rego *opa.OPA) (*Result, error)
}
type Result struct {
Result interface{}
}
type PolicyEntity struct {
ctx context.Context
PolicyName string
InputQuery interface{}
}
func NewPolicyEntity(ctx context.Context, policyName string, inputQuery interface{}) *PolicyEntity {
return &PolicyEntity{
ctx: ctx,
PolicyName: policyName,
InputQuery: inputQuery,
}
}
func Eval(entity *PolicyEntity, rego *opa.OPA) (*Result, error) {
result, err := rego.Eval(entity.ctx, &entity.InputQuery)
if err != nil {
return nil, err
}
return &Result{result.Result}, nil
}
Then I wrote a main function in different packages and execute to check if it works:
package main
import (
"goplayground/pkg/policycenter"
"context"
"fmt"
"github.com/open-policy-agent/golang-opa-wasm/opa"
"io/ioutil"
)
func main() {
input := map[string]interface{}{"Field1": "false", "Field2": "true"}
wasmBytes, err := ioutil.ReadFile("policy.wasm")
if err != nil {
fmt.Printf("error: %v", err)
return
}
rego, err := opa.New().WithPolicyBytes(wasmBytes).Init()
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
defer rego.Close()
ctx := context.Background()
entity := policycenter.NewPolicyEntity(
ctx, "PA", input)
result, _ := policycenter.Eval(entity, rego)
res := result.Result.([]interface{})[0].(map[string]interface{})["result"].(string)
fmt.Println(res)
}
Then the error occuered:

I found that I cannot declare *opa.OPA and policycenter.go at the same time in the main function I wrote above, if I only init opa.OPA or a struct in policycenter.go, the error won't occur.
Here is the example error occurring:
func main() {
wasmBytes, _ := ioutil.ReadFile("policy.wasm")
rego, _ := opa.New().WithPolicyBytes(wasmBytes).Init()
defer rego.Close()
}
func launchEval(rego *opa.OPA, entity *policycenter.PolicyEntity) {
result, err := policycenter.Eval(entity, rego)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
res := result.Result.([]interface{})[0].(map[string]interface{})["result"].(string)
fmt.Println(res)
}
If I delete anything related with policycenter, the error will disappear.
Additional context
I wrote a policycenter_test.go in the packpage and it works well, it seems this compile error is related with opa.OPA reference and declaration in different packages. Here is the code:
package policycenter
import (
"context"
"fmt"
"github.com/open-policy-agent/golang-opa-wasm/opa"
"io/ioutil"
"reflect"
"sync"
"testing"
)
var(
cases = []interface{}{map[string]interface{}{"Fields1": "false", "Fields2": "true"},
map[string]interface{}{"Fields1": "true", "Fields2": "true"},
map[string]interface{}{"Fields1": "false", "Fields2": "false"},
}
ctx = context.Background()
entity0 = NewPolicyEntity(ctx, "Policy", cases[0])
entity1 = NewPolicyEntity(ctx, "Policy, cases[1])
entity2 = NewPolicyEntity(ctx, "Policy", cases[2])
input = []*PolicyEntity{entity0, entity1, entity2}
)
func TestEval(t *testing.T) {
var
wasmBytes, err := ioutil.ReadFile("../../policy.wasm")
if err != nil {
fmt.Printf("error: %v", err)
return
}
rego, err := opa.New().WithPolicyBytes(wasmBytes).Init()
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
defer rego.Close()
var wg sync.WaitGroup
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
t := i % 3
launchEval(t, rego, input[t])
wg.Done()
}()
}
wg.Wait()
}
func launchEval(flag int, rego *opa.OPA, entity *PolicyEntity) {
result, err := Eval(entity, rego)
if err != nil {
fmt.Printf("error: %v\n", err)
return
}
res := result.Result.([]interface{})[0].(map[string]interface{})["result"].(string)
switch flag {
case 0:
if res != "1P" {
fmt.Println("failure occurs, expected 1P while get" + res)
}
fmt.Println("expected 1P " + res)
case 1:
if res != "2P" {
fmt.Println("failure occurs, expected 2P while get" + res)
}
fmt.Println("expected 2P " + res)
case 2:
if res != "3P" {
fmt.Println("failure occurs, expected 3P while get" + res)
}
fmt.Println("expected 3P " + res)
}
}
and the test passed:

this complie error confuses me a lot, why this error occurs?