From 546135db98b8fc2397dca4e4662ac53a2d443dc5 Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Thu, 8 Jul 2021 18:11:40 +0100 Subject: [PATCH] examples: Add OVSDB Server example This required moving the vswitchd schema to it's own package so it can be used by both play_with_ovs and ovsdb-server. Signed-off-by: Dave Tucker --- .gitignore | 10 +- Makefile | 2 +- example/ovsdb-server/main.go | 122 ++++++++++++++++++ example/play_with_ovs/gen.go | 3 - .../{play_with_ovs.go => main..go} | 15 ++- example/vswitchd/gen.go | 3 + 6 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 example/ovsdb-server/main.go delete mode 100644 example/play_with_ovs/gen.go rename example/play_with_ovs/{play_with_ovs.go => main..go} (88%) create mode 100644 example/vswitchd/gen.go diff --git a/.gitignore b/.gitignore index 26350403..b64d0470 100644 --- a/.gitignore +++ b/.gitignore @@ -11,12 +11,6 @@ _obj _test bin -# Generated files -example/play_with_ovs/ovs.ovsschema -example/play_with_ovs/*.go -!example/play_with_ovs/gen.go -!example/play_with_ovs/play_with_ovs.go - # Architecture specific extensions/prefixes *.[568vq] [568vq].out @@ -64,4 +58,6 @@ Temporary Items ### Project-Specific *.out *.cov - +example/vswitchd/ovs.ovsschema +example/vswitchd/*.go +!example/vswitchd/gen.go \ No newline at end of file diff --git a/Makefile b/Makefile index 35370646..69ef8117 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ prebuild: @echo "+ $@" @mkdir -p bin @go build -v -o ./bin ./cmd/modelgen - @[ -f example/play_with_ovs/ovs.ovsschema ] || curl -o example/play_with_ovs/ovs.ovsschema https://raw.githubusercontent.com/openvswitch/ovs/v2.15.0/vswitchd/vswitch.ovsschema + @[ -f example/vswitchd/ovs.ovsschema ] || curl -o example/vswitchd/ovs.ovsschema https://raw.githubusercontent.com/openvswitch/ovs/v2.15.0/vswitchd/vswitch.ovsschema @go generate -v ./... .PHONY: build diff --git a/example/ovsdb-server/main.go b/example/ovsdb-server/main.go new file mode 100644 index 00000000..2d374e1c --- /dev/null +++ b/example/ovsdb-server/main.go @@ -0,0 +1,122 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "os" + "os/signal" + "path/filepath" + "runtime" + "runtime/pprof" + "time" + + "github.com/ovn-org/libovsdb/client" + "github.com/ovn-org/libovsdb/example/vswitchd" + "github.com/ovn-org/libovsdb/model" + "github.com/ovn-org/libovsdb/ovsdb" + "github.com/ovn-org/libovsdb/server" +) + +var ( + cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file") + memprofile = flag.String("memoryprofile", "", "write memory profile to this file") + port = flag.Int("port", 56640, "tcp port to listen on") +) + +func main() { + flag.Parse() + var err error + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal(err) + } + if err := pprof.StartCPUProfile(f); err != nil { + log.Fatal(err) + } + defer pprof.StopCPUProfile() + } + + dbModel, err := vswitchd.FullDatabaseModel() + if err != nil { + log.Fatal(err) + } + wd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } + path := filepath.Join(wd, "vswitchd", "vswitchd.ovsschema") + f, err := os.Open(path) + if err != nil { + log.Fatal(err) + } + schema, err := ovsdb.SchemaFromFile(f) + if err != nil { + log.Fatal(err) + } + + ovsDB := server.NewInMemoryDatabase(map[string]*model.DBModel{ + schema.Name: dbModel, + }) + + s, err := server.NewOvsdbServer(ovsDB, server.DatabaseModel{ + Model: dbModel, + Schema: schema, + }) + if err != nil { + log.Fatal(err) + } + defer s.Close() + + sig := make(chan os.Signal, 1) + signal.Notify(sig, os.Interrupt) + + go func(o *server.OvsdbServer) { + if err := o.Serve("tcp", fmt.Sprintf(":%d", *port)); err != nil { + log.Fatal(err) + } + }(s) + + time.Sleep(1 * time.Second) + c, err := client.NewOVSDBClient(dbModel, client.WithEndpoint(fmt.Sprintf("tcp::%d", *port))) + if err != nil { + log.Fatal(err) + } + + err = c.Connect(context.Background()) + if err != nil { + log.Fatal(err) + } + ovsRow := &vswitchd.OpenvSwitch{ + UUID: "ovs", + } + ovsOps, err := c.Create(ovsRow) + if err != nil { + log.Fatal(err) + } + reply, err := c.Transact(ovsOps...) + if err != nil { + log.Fatal(err) + } + _, err = ovsdb.CheckOperationResults(reply, ovsOps) + if err != nil { + log.Fatal(err) + } + c.Close() + log.Printf("listening on tcp::%d", *port) + <-sig + + if *memprofile != "" { + f, err := os.Create(*memprofile) + if err != nil { + log.Fatal(err) + } + defer f.Close() + runtime.GC() + if err := pprof.WriteHeapProfile(f); err != nil { + log.Fatal("could not write memory profile: ", err) + } + } +} diff --git a/example/play_with_ovs/gen.go b/example/play_with_ovs/gen.go deleted file mode 100644 index 259037ba..00000000 --- a/example/play_with_ovs/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package main - -//go:generate ../../bin/modelgen -p main -o . ovs.ovsschema diff --git a/example/play_with_ovs/play_with_ovs.go b/example/play_with_ovs/main..go similarity index 88% rename from example/play_with_ovs/play_with_ovs.go rename to example/play_with_ovs/main..go index 384d7abc..4b5d8b3a 100644 --- a/example/play_with_ovs/play_with_ovs.go +++ b/example/play_with_ovs/main..go @@ -8,6 +8,7 @@ import ( "github.com/ovn-org/libovsdb/cache" "github.com/ovn-org/libovsdb/client" + "github.com/ovn-org/libovsdb/example/vswitchd" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) @@ -28,14 +29,14 @@ var connection = flag.String("ovsdb", "unix:/var/run/openvswitch/db.sock", "OVSD func play(ovs client.Client) { go processInput(ovs) for model := range update { - bridge := model.(*Bridge) + bridge := model.(*vswitchd.Bridge) if bridge.Name == "stop" { fmt.Printf("Bridge stop detected: %+v\n", *bridge) ovs.Disconnect() quit <- true } else { fmt.Printf("Current list of bridges:\n") - var bridges []Bridge + var bridges []vswitchd.Bridge if err := ovs.List(&bridges); err != nil { log.Fatal(err) } @@ -47,7 +48,7 @@ func play(ovs client.Client) { } func createBridge(ovs client.Client, bridgeName string) { - bridge := Bridge{ + bridge := vswitchd.Bridge{ UUID: "gopher", Name: bridgeName, } @@ -56,7 +57,7 @@ func createBridge(ovs client.Client, bridgeName string) { log.Fatal(err) } - ovsRow := OpenvSwitch{ + ovsRow := vswitchd.OpenvSwitch{ UUID: rootUUID, } mutateOps, err := ovs.Where(&ovsRow).Mutate(&ovsRow, model.Mutation{ @@ -97,7 +98,7 @@ func main() { update = make(chan model.Model) dbModel, err := model.NewDBModel("Open_vSwitch", - map[string]model.Model{bridgeTable: &Bridge{}, ovsTable: &OpenvSwitch{}}) + map[string]model.Model{bridgeTable: &vswitchd.Bridge{}, ovsTable: &vswitchd.OpenvSwitch{}}) if err != nil { log.Fatal("Unable to create DB model ", err) } @@ -120,8 +121,8 @@ func main() { }, }) _, err = ovs.Monitor( - ovs.NewTableMonitor(&OpenvSwitch{}), - ovs.NewTableMonitor(&Bridge{}), + ovs.NewTableMonitor(&vswitchd.OpenvSwitch{}), + ovs.NewTableMonitor(&vswitchd.Bridge{}), ) if err != nil { log.Fatal(err) diff --git a/example/vswitchd/gen.go b/example/vswitchd/gen.go new file mode 100644 index 00000000..3cef8860 --- /dev/null +++ b/example/vswitchd/gen.go @@ -0,0 +1,3 @@ +package vswitchd + +//go:generate ../../bin/modelgen -p vswitchd -o . ovs.ovsschema