mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
fix data race (#1446)
This commit is contained in:
@@ -329,10 +329,8 @@ func generateOpenAPISchemaFromCapabilityParameter(capability types.Capability, p
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
|
||||
var r cue.Runtime
|
||||
cueInst, err := r.Build(bi)
|
||||
cueInst, err := pd.ImportPackagesAndBuildInstance(bi)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -82,6 +82,20 @@ func (pd *PackageDiscover) ImportBuiltinPackagesFor(bi *build.Instance) {
|
||||
bi.Imports = append(bi.Imports, pd.velaBuiltinPackages...)
|
||||
}
|
||||
|
||||
// ImportPackagesAndBuildInstance Combine import built-in packages and build cue template together to avoid data race
|
||||
func (pd *PackageDiscover) ImportPackagesAndBuildInstance(bi *build.Instance) (inst *cue.Instance, err error) {
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
|
||||
var r cue.Runtime
|
||||
pd.mutex.Lock()
|
||||
defer pd.mutex.Unlock()
|
||||
cueInst, err := r.Build(bi)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cueInst, err
|
||||
}
|
||||
|
||||
// ListPackageKinds list packages and their kinds
|
||||
func (pd *PackageDiscover) ListPackageKinds() map[string][]VersionKind {
|
||||
pd.mutex.RLock()
|
||||
@@ -132,6 +146,30 @@ func (pd *PackageDiscover) mount(pkg *pkgInstance, pkgKinds []VersionKind) {
|
||||
pd.velaBuiltinPackages = append(pd.velaBuiltinPackages, pkg.Instance)
|
||||
}
|
||||
|
||||
func (pd *PackageDiscover) pkgBuild(packages map[string]*pkgInstance, pkgName string,
|
||||
dGVK domainGroupVersionKind, def string, kubePkg *pkgInstance, groupKinds map[string][]VersionKind) error {
|
||||
pkg, ok := packages[pkgName]
|
||||
if !ok {
|
||||
pkg = newPackage(pkgName)
|
||||
pkg.Imports = []*build.Instance{kubePkg.Instance}
|
||||
}
|
||||
|
||||
mykinds := groupKinds[pkgName]
|
||||
mykinds = append(mykinds, VersionKind{
|
||||
APIVersion: dGVK.APIVersion,
|
||||
Kind: dGVK.Kind,
|
||||
DefinitionName: "#" + dGVK.Kind,
|
||||
})
|
||||
|
||||
if err := pkg.AddFile(dGVK.reverseString(), def); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
packages[pkgName] = pkg
|
||||
groupKinds[pkgName] = mykinds
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pd *PackageDiscover) addKubeCUEPackagesFromCluster(apiSchema string) error {
|
||||
var r cue.Runtime
|
||||
oaInst, err := r.Compile("-", apiSchema)
|
||||
@@ -180,32 +218,10 @@ kind: "%s"
|
||||
apiVersion: "%s",
|
||||
}`, v.Kind, k, v.Kind, apiVersion)
|
||||
|
||||
pkgBuild := func(pkgName string) error {
|
||||
pkg, ok := packages[pkgName]
|
||||
if !ok {
|
||||
pkg = newPackage(pkgName)
|
||||
pkg.Imports = []*build.Instance{kubePkg.Instance}
|
||||
}
|
||||
|
||||
mykinds := groupKinds[pkgName]
|
||||
mykinds = append(mykinds, VersionKind{
|
||||
APIVersion: v.APIVersion,
|
||||
Kind: v.Kind,
|
||||
DefinitionName: "#" + v.Kind,
|
||||
})
|
||||
|
||||
if err := pkg.AddFile(v.reverseString(), def); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
packages[pkgName] = pkg
|
||||
groupKinds[pkgName] = mykinds
|
||||
return nil
|
||||
}
|
||||
if err := pkgBuild(genStandardPkgName(v)); err != nil {
|
||||
if err := pd.pkgBuild(packages, genStandardPkgName(v), v, def, kubePkg, groupKinds); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := pkgBuild(genOpenPkgName(v)); err != nil {
|
||||
if err := pd.pkgBuild(packages, genOpenPkgName(v), v, def, kubePkg, groupKinds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"cuelang.org/go/cue"
|
||||
"cuelang.org/go/cue/build"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
@@ -100,7 +99,6 @@ var _ = Describe("Package discovery resources for definition from K8s APIServer"
|
||||
|
||||
By("test ingress in kube package")
|
||||
bi := build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
err := bi.AddFile("-", `
|
||||
import (
|
||||
kube "kube/networking.k8s.io/v1beta1"
|
||||
@@ -134,8 +132,7 @@ parameter: {
|
||||
}
|
||||
}`)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
var r cue.Runtime
|
||||
inst, err := r.Build(bi)
|
||||
inst, err := pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err := model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -161,7 +158,6 @@ parameter: {
|
||||
})).Should(BeEquivalentTo(""))
|
||||
By("test Invalid Import path")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
kube "kube/networking.k8s.io/v1"
|
||||
@@ -183,7 +179,7 @@ parameter: {
|
||||
name: "myapp"
|
||||
image: "nginx"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).ShouldNot(BeNil())
|
||||
@@ -191,7 +187,6 @@ parameter: {
|
||||
|
||||
By("test Deployment in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
kube "kube/apps/v1"
|
||||
@@ -212,7 +207,7 @@ parameter: {
|
||||
name: "myapp"
|
||||
image: "nginx"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -234,7 +229,6 @@ parameter: {
|
||||
|
||||
By("test Secret in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
kube "kube/v1"
|
||||
@@ -249,7 +243,7 @@ output: {
|
||||
parameter: {
|
||||
name: "myapp"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -263,7 +257,6 @@ parameter: {
|
||||
|
||||
By("test Service in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
kube "kube/v1"
|
||||
@@ -278,7 +271,7 @@ output: {
|
||||
parameter: {
|
||||
name: "myapp"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -367,7 +360,6 @@ parameter: {
|
||||
}, time.Second*30, time.Millisecond*300).Should(BeNil())
|
||||
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
err = bi.AddFile("-", `
|
||||
import (
|
||||
kv1 "kube/example.com/v1"
|
||||
@@ -379,7 +371,7 @@ output: {
|
||||
}
|
||||
`)
|
||||
Expect(err).Should(BeNil())
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -400,7 +392,6 @@ output: {
|
||||
|
||||
By("test ingress in kube package")
|
||||
bi := build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
err := bi.AddFile("-", `
|
||||
import (
|
||||
network "k8s.io/networking/v1beta1"
|
||||
@@ -432,8 +423,7 @@ parameter: {
|
||||
}
|
||||
}`)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
var r cue.Runtime
|
||||
inst, err := r.Build(bi)
|
||||
inst, err := pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err := model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -459,7 +449,6 @@ parameter: {
|
||||
})).Should(BeEquivalentTo(""))
|
||||
By("test Invalid Import path")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
"k8s.io/networking/v1"
|
||||
@@ -481,7 +470,7 @@ parameter: {
|
||||
name: "myapp"
|
||||
image: "nginx"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).ShouldNot(BeNil())
|
||||
@@ -489,7 +478,6 @@ parameter: {
|
||||
|
||||
By("test Deployment in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
apps "k8s.io/apps/v1"
|
||||
@@ -510,7 +498,7 @@ parameter: {
|
||||
name: "myapp"
|
||||
image: "nginx"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -532,7 +520,6 @@ parameter: {
|
||||
|
||||
By("test Secret in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
"k8s.io/core/v1"
|
||||
@@ -547,7 +534,7 @@ output: {
|
||||
parameter: {
|
||||
name: "myapp"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -561,7 +548,6 @@ parameter: {
|
||||
|
||||
By("test Service in kube package")
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import (
|
||||
"k8s.io/core/v1"
|
||||
@@ -576,7 +562,7 @@ output: {
|
||||
parameter: {
|
||||
name: "myapp"
|
||||
}`)
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -665,7 +651,6 @@ parameter: {
|
||||
}, time.Second*30, time.Millisecond*300).Should(BeNil())
|
||||
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
pd.ImportBuiltinPackagesFor(bi)
|
||||
err = bi.AddFile("-", `
|
||||
import (
|
||||
ev1 "example.com/v1"
|
||||
@@ -677,7 +662,7 @@ output: {
|
||||
}
|
||||
`)
|
||||
Expect(err).Should(BeNil())
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = pd.ImportPackagesAndBuildInstance(bi)
|
||||
Expect(err).Should(BeNil())
|
||||
base, err = model.NewBase(inst.Lookup("output"))
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -407,26 +407,22 @@ func TestPackage(t *testing.T) {
|
||||
})
|
||||
`
|
||||
bi := build.NewContext().NewInstance("", nil)
|
||||
mypd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import "test.io/apps/v1"
|
||||
output: v1.#Bucket
|
||||
`)
|
||||
var r cue.Runtime
|
||||
inst, err := r.Build(bi)
|
||||
inst, err := mypd.ImportPackagesAndBuildInstance(bi)
|
||||
assert.NilError(t, err)
|
||||
base, err := model.NewBase(inst.Value())
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, base.String(), exceptObj)
|
||||
|
||||
bi = build.NewContext().NewInstance("", nil)
|
||||
mypd.ImportBuiltinPackagesFor(bi)
|
||||
bi.AddFile("-", `
|
||||
import "kube/apps.test.io/v1"
|
||||
output: v1.#Bucket
|
||||
`)
|
||||
|
||||
inst, err = r.Build(bi)
|
||||
inst, err = mypd.ImportPackagesAndBuildInstance(bi)
|
||||
assert.NilError(t, err)
|
||||
base, err = model.NewBase(inst.Value())
|
||||
assert.NilError(t, err)
|
||||
|
||||
@@ -103,9 +103,8 @@ func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string, pa
|
||||
if err := bi.AddFile("-", ctx.ExtendedContextFile()); err != nil {
|
||||
return err
|
||||
}
|
||||
wd.pd.ImportBuiltinPackagesFor(bi)
|
||||
var r cue.Runtime
|
||||
inst, err := r.Build(bi)
|
||||
|
||||
inst, err := wd.pd.ImportPackagesAndBuildInstance(bi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -285,52 +284,52 @@ func (td *traitDef) Complete(ctx process.Context, abstractTemplate string, param
|
||||
if err := bi.AddFile("context", ctx.ExtendedContextFile()); err != nil {
|
||||
return errors.WithMessagef(err, "invalid context of trait %s", td.name)
|
||||
}
|
||||
td.pd.ImportBuiltinPackagesFor(bi)
|
||||
|
||||
instances := cue.Build([]*build.Instance{bi})
|
||||
for _, inst := range instances {
|
||||
if err := inst.Value().Err(); err != nil {
|
||||
return errors.WithMessagef(err, "invalid template of trait %s after merge with parameter and context", td.name)
|
||||
}
|
||||
processing := inst.Lookup("processing")
|
||||
var err error
|
||||
if processing.Exists() {
|
||||
if inst, err = task.Process(inst); err != nil {
|
||||
return errors.WithMessagef(err, "invalid process of trait %s", td.name)
|
||||
}
|
||||
}
|
||||
inst, err := td.pd.ImportPackagesAndBuildInstance(bi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outputs := inst.Lookup(OutputsFieldName)
|
||||
if outputs.Exists() {
|
||||
st, err := outputs.Struct()
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid outputs of trait %s", td.name)
|
||||
}
|
||||
for i := 0; i < st.Len(); i++ {
|
||||
fieldInfo := st.Field(i)
|
||||
if fieldInfo.IsDefinition || fieldInfo.IsHidden || fieldInfo.IsOptional {
|
||||
continue
|
||||
}
|
||||
other, err := model.NewOther(fieldInfo.Value)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid outputs(resource=%s) of trait %s", fieldInfo.Name, td.name)
|
||||
}
|
||||
ctx.AppendAuxiliaries(process.Auxiliary{Ins: other, Type: td.name, Name: fieldInfo.Name})
|
||||
}
|
||||
}
|
||||
|
||||
patcher := inst.Lookup(PatchFieldName)
|
||||
if patcher.Exists() {
|
||||
base, _ := ctx.Output()
|
||||
p, err := model.NewOther(patcher)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid patch of trait %s", td.name)
|
||||
}
|
||||
if err := base.Unify(p); err != nil {
|
||||
return errors.WithMessagef(err, "invalid patch trait %s into workload", td.name)
|
||||
}
|
||||
if err := inst.Value().Err(); err != nil {
|
||||
return errors.WithMessagef(err, "invalid template of trait %s after merge with parameter and context", td.name)
|
||||
}
|
||||
processing := inst.Lookup("processing")
|
||||
if processing.Exists() {
|
||||
if inst, err = task.Process(inst); err != nil {
|
||||
return errors.WithMessagef(err, "invalid process of trait %s", td.name)
|
||||
}
|
||||
}
|
||||
outputs := inst.Lookup(OutputsFieldName)
|
||||
if outputs.Exists() {
|
||||
st, err := outputs.Struct()
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid outputs of trait %s", td.name)
|
||||
}
|
||||
for i := 0; i < st.Len(); i++ {
|
||||
fieldInfo := st.Field(i)
|
||||
if fieldInfo.IsDefinition || fieldInfo.IsHidden || fieldInfo.IsOptional {
|
||||
continue
|
||||
}
|
||||
other, err := model.NewOther(fieldInfo.Value)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid outputs(resource=%s) of trait %s", fieldInfo.Name, td.name)
|
||||
}
|
||||
ctx.AppendAuxiliaries(process.Auxiliary{Ins: other, Type: td.name, Name: fieldInfo.Name})
|
||||
}
|
||||
}
|
||||
|
||||
patcher := inst.Lookup(PatchFieldName)
|
||||
if patcher.Exists() {
|
||||
base, _ := ctx.Output()
|
||||
p, err := model.NewOther(patcher)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "invalid patch of trait %s", td.name)
|
||||
}
|
||||
if err := base.Unify(p); err != nil {
|
||||
return errors.WithMessagef(err, "invalid patch trait %s into workload", td.name)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user