fix data race (#1446)

This commit is contained in:
yangsoon
2021-04-09 20:15:02 +08:00
committed by GitHub
parent e5a9be8de9
commit 2e92a66fa5
5 changed files with 99 additions and 105 deletions
+1 -3
View File
@@ -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
}
+40 -24
View File
@@ -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
}
}
+12 -27
View File
@@ -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())
+2 -6
View File
@@ -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)
+44 -45
View File
@@ -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
}