Skip to content

Commit

Permalink
ovn: introduce ovnmetagen
Browse files Browse the repository at this point in the history
As a first step to enhance ovn support, autogenerate types based on a
ovn schema file leveraging github.com/ovn-org/libovsdb new
functionalities.

By autogenerting this structs we are able to:
- Use the same struct for both skydive and ovn decoding (removing
  copies)
- Inspect every table in the database without writing any code
- Support any OVN version without writing any code
- Automatically detect the intrisic "links" between tables

Signed-off-by: Adrian Moreno <[email protected]>
  • Loading branch information
amorenoz committed Jul 12, 2021
1 parent 1f5c086 commit a11dcb3
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .mk/easyjson.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
GEN_EASYJSON_FILES = $(patsubst %.go,%_easyjson.go,$(shell git grep //go:generate | grep "easyjson" | grep -v Makefile | cut -d ":" -f 1))
GEN_EASYJSON_FILES = $(patsubst %.go,%_easyjson.go,$(shell git grep //go:generate | grep "easyjson" | grep -v ovnmetagen | grep -v Makefile | cut -d ":" -f 1))
GEN_EASYJSON_FILES += flow/flow.pb_easyjson.go

%_easyjson.go: %.go
Expand Down
2 changes: 1 addition & 1 deletion .mk/gendecoder.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
GEN_DECODER_FILES = $(patsubst %.go,%_gendecoder.go,$(shell git grep //go:generate | grep "gendecoder" | grep -v "\.mk" | cut -d ":" -f 1))
GEN_DECODER_FILES = $(patsubst %.go,%_gendecoder.go,$(shell git grep //go:generate | grep "gendecoder" | grep -v ovnmetagen | grep -v "\.mk" | cut -d ":" -f 1))
GEN_DECODER_FILES += flow/flow.pb_gendecoder.go

%_gendecoder.go: %.go
Expand Down
27 changes: 27 additions & 0 deletions .mk/ovn.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
OVN_VERSION ?= branch-20.12
SCHEMA_REMOTE_FILE = https://raw.githubusercontent.com/ovn-org/ovn/$(OVN_VERSION)/ovn-nb.ovsschema
MODEL_DIR = topology/probes/ovn/ovnmodel/
GEN_DIR = topology/probes/ovn/ovnmetagen
GEN_BIN = $(GEN_DIR)/ovnmetagen
SCHEMA_FILE = $(MODEL_DIR)/ovn-nb.ovsschema


$(SCHEMA_FILE):
curl -o $@ $(SCHEMA_REMOTE_FILE)

$(GEN_BIN):
go build -o $(GEN_DIR) ./$(GEN_DIR)

.PHONY: .ovnmodel
.ovnmodel: $(SCHEMA_FILE) $(GEN_BIN)
# TODO: add WITH_OVN flag
#ifeq ($(WITH_OVN), true)
go generate -tags "${BUILD_TAGS}" topology/probes/ovn/ovnmodel/gen.go
#endif

.PHONY: .ovnmodel.clean
.ovnmodel.clean:
@grep -r 'generated by ovnmetagen' $(MODEL_DIR) | cut -d: -f 1 | xargs rm -f
@rm -f $(SCHEMA_FILE)
@rm -f $(GEN_BIN)

5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ include .mk/tests.mk
include .mk/vppapi.mk
include .mk/swagger.mk
include .mk/stringer.mk
include .mk/ovn.mk

.DEFAULT_GOAL := all

Expand Down Expand Up @@ -162,13 +163,13 @@ ifneq ($(OFFLINE), true)
endif

.PHONY: genlocalfiles
genlocalfiles: $(EXTRA_BUILD_TARGET) .proto .typescript .bindata .gendecoder .easyjson .vppbinapi
genlocalfiles: $(EXTRA_BUILD_TARGET) .proto .typescript .bindata .ovnmodel .gendecoder .easyjson .vppbinapi

.PHONY: touchlocalfiles
touchlocalfiles: .proto.touch .typescript.touch .bindata.touch .gendecoder.touch .easyjson.touch

.PHONY: clean
clean: skydive.clean test.functionals.clean contribs.clean .ebpf.clean .easyjson.clean .proto.clean .gendecoder.clean .typescript.clean .vppbinapi.clean swagger.clean
clean: skydive.clean test.functionals.clean contribs.clean .ebpf.clean .easyjson.clean .proto.clean .gendecoder.clean .ovnmodel.clean .typescript.clean .vppbinapi.clean swagger.clean
go clean -i >/dev/null 2>&1 || true

.PHONY: docker
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@ require (
github.com/avast/retry-go v3.0.0+incompatible
github.com/bennyscetbun/jsongo v0.0.0-20190110163710-9624bef8c57b // indirect
github.com/casbin/casbin v1.9.1
github.com/cenk/hub v0.0.0-20160527103212-11382a9960d3 // indirect
github.com/cenk/rpc2 v0.0.0-20160427170138-7ab76d2e88c7 // indirect
github.com/cenkalti/rpc2 v0.0.0-20180727162946-9642ea02d0aa // indirect
github.com/cnf/structhash v0.0.0-20201013183111-a92e111048cd
github.com/coreos/etcd v3.3.22+incompatible
github.com/davecgh/go-spew v1.1.1
github.com/digitalocean/go-libvirt v0.0.0-20190715144809-7b622097a793
github.com/docker/docker v1.13.1
github.com/ebay/go-ovn v0.0.0-20190726163905-ca0da4d10c52
github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/gima/govalid v0.0.0-20150214172340-7b486932bea2
Expand Down Expand Up @@ -62,6 +59,7 @@ require (
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d
github.com/olivere/elastic/v7 v7.0.21
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
github.com/ovn-org/libovsdb v0.4.0
github.com/pelletier/go-toml v1.7.0 // indirect
github.com/pierrec/xxHash v0.1.5
github.com/pkg/errors v0.9.1
Expand Down
81 changes: 81 additions & 0 deletions topology/probes/ovn/ovnmetagen/links.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions topology/probes/ovn/ovnmetagen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package main

import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/ovn-org/libovsdb/modelgen"
"github.com/ovn-org/libovsdb/ovsdb"
)

func usage() {
fmt.Fprintf(os.Stderr, "Usage of ovnmetagen:\n")
fmt.Fprintf(os.Stderr, "\tovnmetagen [flags] OVS_SCHEMA\n")
fmt.Fprintf(os.Stderr, "Flags:\n")
flag.PrintDefaults()
}

var (
outDirP = flag.String("o", ".", "Directory where the generated files shall be stored")
pkgNameP = flag.String("p", "ovsmodel", "Package name")
dryRun = flag.Bool("d", false, "Dry run")
)

func main() {
log.SetFlags(0)
log.SetPrefix("ovnmetagen: ")
flag.Usage = usage
flag.Parse()
outDir := *outDirP
pkgName := *pkgNameP

outDir, err := filepath.Abs(outDir)
if err != nil {
log.Fatal(err)
}

if err := os.MkdirAll(outDir, 0755); err != nil {
log.Fatal(err)
}

if len(flag.Args()) != 1 {
flag.Usage()
os.Exit(2)
}

schemaFile, err := os.Open(flag.Args()[0])
if err != nil {
log.Fatal(err)
}
defer schemaFile.Close()

schemaBytes, err := ioutil.ReadAll(schemaFile)
if err != nil {
log.Fatal(err)
}

var dbSchema ovsdb.DatabaseSchema
if err := json.Unmarshal(schemaBytes, &dbSchema); err != nil {
log.Fatal(err)
}

generator := modelgen.NewGenerator(*dryRun)

for name := range dbSchema.Tables {
templ, data := tableTemplate(pkgName, name, &dbSchema)
err := generator.Generate(modelgen.FileName(name), templ, data)
if err != nil {
log.Printf("Error creating table template: %s", name)
log.Fatal(err)
}
}

dbTempl, dbData := modelTemplate(pkgName, &dbSchema)
if err != nil {
log.Print("Error creating DBModel template")
log.Fatal(err)
}
err = generator.Generate("model.go", dbTempl, dbData)
if err != nil {
log.Fatal(err)
}

linksTempl, lData := linksTemplate(pkgName, &dbSchema)
if err != nil {
log.Print("Error creating links template")
log.Fatal(err)
}
err = generator.Generate("links.go", linksTempl, lData)
if err != nil {
log.Fatal(err)
}
}
50 changes: 50 additions & 0 deletions topology/probes/ovn/ovnmetagen/model.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a11dcb3

Please sign in to comment.