From 08f862005815dde18e108e87472d9a902fe22d62 Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Mon, 28 Jun 2021 18:30:04 +0100 Subject: [PATCH] Add opentelemetry support 1. Added context.Context to most API methods for span propagation 2. Spans are added to the parent (from context) when an API is called 3. Simple cache metrics can be registered with cache.RegisterMetrics() Signed-off-by: Dave Tucker --- .github/workflows/ci.yml | 50 +++++- Dockerfile | 12 ++ cache/cache.go | 49 +++++- cache/cache_test.go | 21 +-- client/client.go | 35 +++- cmd/stress/stress.go | 80 ++++++++- example/opentelemetry/docker-compose.yml | 47 +++++ example/opentelemetry/otel.yaml | 43 +++++ example/opentelemetry/prometheus.yaml | 6 + example/play_with_ovs/main.go | 15 +- go.mod | 10 +- go.sum | 214 ++++++++++++++++++++++- ovs/start.sh | 2 +- server/database.go | 47 +++-- server/server.go | 34 ++-- server/server_integration_test.go | 3 +- server/server_test.go | 12 +- server/transact.go | 59 ++++--- server/transact_test.go | 27 +-- 19 files changed, 660 insertions(+), 106 deletions(-) create mode 100644 Dockerfile create mode 100644 example/opentelemetry/docker-compose.yml create mode 100644 example/opentelemetry/otel.yaml create mode 100644 example/opentelemetry/prometheus.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e7d919e..02ebb64d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,7 +85,7 @@ jobs: - 2.13.0 runs-on: ubuntu-latest - + steps: - name: Set up Go 1.16 uses: actions/setup-go@v1 @@ -99,4 +99,50 @@ jobs: - name: Integration Test run: make integration-test env: - OVS_IMAGE_TAG: ${{ matrix.ovs_version }} \ No newline at end of file + OVS_IMAGE_TAG: ${{ matrix.ovs_version }} + + images: + needs: build + name: Build Image + runs-on: ubuntu-latest + strategy: + matrix: + cmd: [modelgen, print_schema, stress] + + steps: + - name: Check Out Repo + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Login to Docker Hub + if: ${{ contains(github.ref, 'refs/head/main') }} + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Build and push + id: docker_build + uses: docker/build-push-action@v2 + with: + context: . + target: ${{ matrix.cmd }} + builder: ${{ steps.buildx.outputs.name }} + push: ${{ contains(github.ref, 'refs/head/main') }} + tags: libovsdb/${{ matrix.cmd }}:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..8cac8e71 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.16-alpine as base +COPY . /src +WORKDIR /src + +FROM base as stress +RUN go install ./cmd/stress + +FROM base as print_schema +RUN go install ./cmd/print_schema + +FROM base as modelgen +RUN go install ./cmd/modelgen \ No newline at end of file diff --git a/cache/cache.go b/cache/cache.go index e32e5d7a..1a96b5a3 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -2,6 +2,7 @@ package cache import ( "bytes" + "context" "crypto/sha256" "encoding/gob" "encoding/hex" @@ -15,8 +16,13 @@ import ( "github.com/ovn-org/libovsdb/mapper" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/global" ) +var tracer = otel.Tracer("libovsdb.ovn.org/cache") + const ( updateEvent = "update" addEvent = "add" @@ -437,6 +443,7 @@ func NewTableCache(schema *ovsdb.DatabaseSchema, dbModel *model.DBModel, data Da } } } + return &TableCache{ cache: cache, schema: schema, @@ -480,20 +487,20 @@ func (t *TableCache) Tables() []string { // Update implements the update method of the NotificationHandler interface // this populates the cache with new updates -func (t *TableCache) Update(context interface{}, tableUpdates ovsdb.TableUpdates) { +func (t *TableCache) Update(ctx context.Context, monitorID interface{}, tableUpdates ovsdb.TableUpdates) { if len(tableUpdates) == 0 { return } - t.Populate(tableUpdates) + t.Populate(ctx, tableUpdates) } // Update2 implements the update method of the NotificationHandler interface // this populates the cache with new updates -func (t *TableCache) Update2(context interface{}, tableUpdates ovsdb.TableUpdates2) { +func (t *TableCache) Update2(ctx context.Context, monitorID interface{}, tableUpdates ovsdb.TableUpdates2) { if len(tableUpdates) == 0 { return } - t.Populate2(tableUpdates) + t.Populate2(ctx, tableUpdates) } // Locked implements the locked method of the NotificationHandler interface @@ -512,8 +519,36 @@ func (t *TableCache) Echo([]interface{}) { func (t *TableCache) Disconnected() { } +// RegisterMetrics registers a metric for all known tables +func (t *TableCache) RegisterMetrics() error { + for _, tt := range t.Tables() { + if err := t.registerMetric(tt); err != nil { + return err + } + } + return nil +} + +func (t *TableCache) registerMetric(table string) error { + meter := global.Meter("libovsdb.ovn.org/cache") + if _, ok := t.cache[table]; !ok { + return fmt.Errorf("table not found") + } + _, err := meter.NewInt64ValueObserver( + fmt.Sprintf("libovsdb.cache.%s.size", strings.ToLower(table)), + func(ctx context.Context, result metric.Int64ObserverResult) { + value := t.Table(table).Len() + result.Observe(int64(value)) + }, + metric.WithDescription(fmt.Sprintf("the size of the %s table in the cache", strings.ToLower(table))), + ) + return err +} + // Populate adds data to the cache and places an event on the channel -func (t *TableCache) Populate(tableUpdates ovsdb.TableUpdates) { +func (t *TableCache) Populate(ctx context.Context, tableUpdates ovsdb.TableUpdates) { + _, span := tracer.Start(ctx, "cache_populate") + defer span.End() t.mutex.Lock() defer t.mutex.Unlock() @@ -560,7 +595,9 @@ func (t *TableCache) Populate(tableUpdates ovsdb.TableUpdates) { } // Populate2 adds data to the cache and places an event on the channel -func (t *TableCache) Populate2(tableUpdates ovsdb.TableUpdates2) { +func (t *TableCache) Populate2(ctx context.Context, tableUpdates ovsdb.TableUpdates2) { + _, span := tracer.Start(ctx, "cache_populate2") + defer span.End() t.mutex.Lock() defer t.mutex.Unlock() for table := range t.dbModel.Types() { diff --git a/cache/cache_test.go b/cache/cache_test.go index 411aa785..fc77c6f7 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -1,6 +1,7 @@ package cache import ( + "context" "encoding/json" "reflect" "testing" @@ -721,7 +722,7 @@ func TestTableCache_populate(t *testing.T) { }, }, } - tc.Populate(updates) + tc.Populate(context.Background(), updates) got := tc.Table("Open_vSwitch").Row("test") assert.Equal(t, testRowModel, got) @@ -733,7 +734,7 @@ func TestTableCache_populate(t *testing.T) { Old: &testRow, New: &updatedRow, } - tc.Populate(updates) + tc.Populate(context.Background(), updates) got = tc.cache["Open_vSwitch"].cache["test"] assert.Equal(t, updatedRowModel, got) @@ -744,7 +745,7 @@ func TestTableCache_populate(t *testing.T) { New: nil, } - tc.Populate(updates) + tc.Populate(context.Background(), updates) _, ok := tc.cache["Open_vSwitch"].cache["test"] assert.False(t, ok) @@ -786,7 +787,7 @@ func TestTableCachePopulate(t *testing.T) { }, }, } - tc.Populate(updates) + tc.Populate(context.TODO(), updates) got := tc.Table("Open_vSwitch").Row("test") assert.Equal(t, testRowModel, got) @@ -798,7 +799,7 @@ func TestTableCachePopulate(t *testing.T) { Old: &testRow, New: &updatedRow, } - tc.Populate(updates) + tc.Populate(context.TODO(), updates) got = tc.cache["Open_vSwitch"].cache["test"] assert.Equal(t, updatedRowModel, got) @@ -809,7 +810,7 @@ func TestTableCachePopulate(t *testing.T) { New: nil, } - tc.Populate(updates) + tc.Populate(context.TODO(), updates) _, ok := tc.cache["Open_vSwitch"].cache["test"] assert.False(t, ok) @@ -851,7 +852,7 @@ func TestTableCachePopulate2(t *testing.T) { } t.Log("Initial") - tc.Populate2(updates) + tc.Populate2(context.TODO(), updates) got := tc.Table("Open_vSwitch").Row("test") assert.Equal(t, testRowModel, got) @@ -865,7 +866,7 @@ func TestTableCachePopulate2(t *testing.T) { }, }, } - tc.Populate2(updates) + tc.Populate2(context.TODO(), updates) got = tc.Table("Open_vSwitch").Row("test2") assert.Equal(t, testRowModel2, got) @@ -879,7 +880,7 @@ func TestTableCachePopulate2(t *testing.T) { }, }, } - tc.Populate2(updates) + tc.Populate2(context.TODO(), updates) got = tc.cache["Open_vSwitch"].cache["test"] assert.Equal(t, updatedRowModel, got) @@ -892,7 +893,7 @@ func TestTableCachePopulate2(t *testing.T) { }, }, } - tc.Populate2(updates) + tc.Populate2(context.TODO(), updates) _, ok := tc.cache["Open_vSwitch"].cache["test"] assert.False(t, ok) } diff --git a/client/client.go b/client/client.go index 066d7f43..e8c59189 100644 --- a/client/client.go +++ b/client/client.go @@ -21,6 +21,7 @@ import ( "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" "github.com/ovn-org/libovsdb/ovsdb/serverdb" + "go.opentelemetry.io/otel" ) // Constants defined for libovsdb @@ -41,6 +42,9 @@ var ErrAlreadyConnected = errors.New("already connected") // ErrUnsupportedRPC is an error returned when an unsupported RPC method is called var ErrUnsupportedRPC = errors.New("unsupported rpc") +// tracer is the tracer for opentelemetry +var tracer = otel.Tracer("libovsdb.ovn.org/client") + // Client represents an OVSDB Client Connection // It provides all the necessary functionality to Connect to a server, // perform transactions, and build your own replica of the database with @@ -473,6 +477,8 @@ func (o *ovsdbClient) echo(args []interface{}, reply *[]interface{}) error { // - json-value: the arbitrary json-value passed when creating the Monitor, i.e. the "cookie" // - table-updates: map of table name to table-update. Table-update is a map of uuid to (old, new) row paris func (o *ovsdbClient) update(params []json.RawMessage, reply *[]interface{}) error { + ctx, span := tracer.Start(context.Background(), "update") + defer span.End() cookie := MonitorCookie{} if len(params) > 2 { return fmt.Errorf("update requires exactly 2 args") @@ -492,7 +498,7 @@ func (o *ovsdbClient) update(params []json.RawMessage, reply *[]interface{}) err } // Update the local DB cache with the tableUpdates db.cacheMutex.RLock() - db.cache.Update(cookie.ID, updates) + db.cache.Update(ctx, cookie.ID, updates) db.cacheMutex.RUnlock() *reply = []interface{}{} return nil @@ -500,6 +506,8 @@ func (o *ovsdbClient) update(params []json.RawMessage, reply *[]interface{}) err // update2 handling from ovsdb-server.7 func (o *ovsdbClient) update2(params []json.RawMessage, reply *[]interface{}) error { + ctx, span := tracer.Start(context.Background(), "update2") + defer span.End() cookie := MonitorCookie{} if len(params) > 2 { return fmt.Errorf("update2 requires exactly 2 args") @@ -519,7 +527,7 @@ func (o *ovsdbClient) update2(params []json.RawMessage, reply *[]interface{}) er } // Update the local DB cache with the tableUpdates db.cacheMutex.RLock() - db.cache.Update2(cookie, updates) + db.cache.Update2(ctx, cookie, updates) db.cacheMutex.RUnlock() *reply = []interface{}{} return nil @@ -527,6 +535,8 @@ func (o *ovsdbClient) update2(params []json.RawMessage, reply *[]interface{}) er // update3 handling from ovsdb-server.7 func (o *ovsdbClient) update3(params []json.RawMessage, reply *[]interface{}) error { + ctx, span := tracer.Start(context.Background(), "update3") + defer span.End() cookie := MonitorCookie{} if len(params) > 3 { return fmt.Errorf("update requires exactly 3 args") @@ -557,7 +567,7 @@ func (o *ovsdbClient) update3(params []json.RawMessage, reply *[]interface{}) er // Update the local DB cache with the tableUpdates db.cacheMutex.RLock() - db.cache.Update2(cookie, updates) + db.cache.Update2(ctx, cookie, updates) db.cacheMutex.RUnlock() *reply = []interface{}{} return nil @@ -567,6 +577,8 @@ func (o *ovsdbClient) update3(params []json.RawMessage, reply *[]interface{}) er // RFC 7047 : get_schema // Should only be called when mutex is held func (o *ovsdbClient) getSchema(ctx context.Context, dbName string) (*ovsdb.DatabaseSchema, error) { + _, span := tracer.Start(ctx, "get_schema") + defer span.End() args := ovsdb.NewGetSchemaArgs(dbName) var reply ovsdb.DatabaseSchema err := o.rpcClient.CallWithContext(ctx, "get_schema", args, &reply) @@ -583,6 +595,8 @@ func (o *ovsdbClient) getSchema(ctx context.Context, dbName string) (*ovsdb.Data // RFC 7047 : list_dbs // Should only be called when mutex is held func (o *ovsdbClient) listDbs(ctx context.Context) ([]string, error) { + _, span := tracer.Start(ctx, "list_dbs") + defer span.End() var dbs []string err := o.rpcClient.CallWithContext(ctx, "list_dbs", nil, &dbs) if err != nil { @@ -603,6 +617,9 @@ func (o *ovsdbClient) Transact(ctx context.Context, operation ...ovsdb.Operation } func (o *ovsdbClient) transact(ctx context.Context, dbName string, operation ...ovsdb.Operation) ([]ovsdb.OperationResult, error) { + _, span := tracer.Start(ctx, "transact") + defer span.End() + span.AddEvent("validating operations") var reply []ovsdb.OperationResult db := o.databases[dbName] db.schemaMutex.RLock() @@ -631,6 +648,8 @@ func (o *ovsdbClient) transact(ctx context.Context, dbName string, operation ... // MonitorAll is a convenience method to monitor every table/column func (o *ovsdbClient) MonitorAll(ctx context.Context) (MonitorCookie, error) { + ctx, span := tracer.Start(ctx, "monitor_all") + defer span.End() m := newMonitor() for name := range o.primaryDB().model.Types() { m.Tables = append(m.Tables, TableMonitor{Table: name}) @@ -641,6 +660,8 @@ func (o *ovsdbClient) MonitorAll(ctx context.Context) (MonitorCookie, error) { // MonitorCancel will request cancel a previously issued monitor request // RFC 7047 : monitor_cancel func (o *ovsdbClient) MonitorCancel(ctx context.Context, cookie MonitorCookie) error { + _, span := tracer.Start(ctx, "monitor_cancel") + defer span.End() var reply ovsdb.OperationResult args := ovsdb.NewMonitorCancelArgs(cookie) o.rpcMutex.Lock() @@ -678,6 +699,8 @@ func (o *ovsdbClient) Monitor(ctx context.Context, monitor *Monitor) (MonitorCoo } func (o *ovsdbClient) monitor(ctx context.Context, cookie MonitorCookie, reconnecting bool, monitor *Monitor) error { + _, span := tracer.Start(ctx, "monitor") + defer span.End() if len(monitor.Tables) == 0 { return fmt.Errorf("at least one table should be monitored") } @@ -775,18 +798,20 @@ func (o *ovsdbClient) monitor(ctx context.Context, cookie MonitorCookie, reconne u := tableUpdates.(ovsdb.TableUpdates) db.cacheMutex.Lock() defer db.cacheMutex.Unlock() - db.cache.Update(nil, u) + db.cache.Update(ctx, nil, u) } else { u := tableUpdates.(ovsdb.TableUpdates2) db.cacheMutex.Lock() defer db.cacheMutex.Unlock() - db.cache.Update2(nil, u) + db.cache.Update2(ctx, nil, u) } return nil } // Echo tests the liveness of the OVSDB connetion func (o *ovsdbClient) Echo(ctx context.Context) error { + _, span := tracer.Start(ctx, "echo") + defer span.End() args := ovsdb.NewEchoArgs() var reply []interface{} o.rpcMutex.RLock() diff --git a/cmd/stress/stress.go b/cmd/stress/stress.go index 511bb724..3e504dbf 100644 --- a/cmd/stress/stress.go +++ b/cmd/stress/stress.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "log" + "net/http" "os" "runtime" "runtime/pprof" @@ -17,6 +18,20 @@ import ( "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" + export "go.opentelemetry.io/otel/sdk/export/metric" + "go.opentelemetry.io/otel/sdk/metric/aggregator/histogram" + controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" + processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" + selector "go.opentelemetry.io/otel/sdk/metric/selector/simple" + "google.golang.org/grpc" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/metric/global" + "go.opentelemetry.io/otel/propagation" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/exporters/prometheus" ) // ORMBridge is the simplified ORM model of the Bridge table @@ -38,6 +53,7 @@ type ovsType struct { var ( cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file") memprofile = flag.String("memoryprofile", "", "write memory profile to this file") + otlp = flag.String("otlp", "", "otlp grpc endpoint address for trace and metrics. e.g localhost:4317") nins = flag.Int("inserts", 100, "the number of insertions to make to the database (per client)") nclients = flag.Int("clients", 1, "the number of clients to use") parallel = flag.Bool("parallel", false, "run clients in parallel") @@ -106,6 +122,10 @@ func run(ctx context.Context, resultsChan chan result, wg *sync.WaitGroup) { } defer ovs.Disconnect() + if err := ovs.Cache().RegisterMetrics(); err != nil { + log.Fatal(err) + } + var bridges []bridgeType bridgeCh := make(map[string]chan bool) for i := 0; i < *nins; i++ { @@ -234,6 +254,53 @@ func main() { flag.Parse() ctx := context.Background() + if *otlp != "" { + traceExporter, err := otlptracegrpc.New(ctx, + otlptracegrpc.WithInsecure(), + otlptracegrpc.WithEndpoint(*otlp), + otlptracegrpc.WithDialOption(grpc.WithBlock()), + ) + if err != nil { + log.Fatalf("failed to initialize export pipeline: %v", err) + } + bsp := sdktrace.NewBatchSpanProcessor(traceExporter) + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithSpanProcessor(bsp), + ) + otel.SetTracerProvider(tracerProvider) + + // set global propagator to tracecontext (the default is no-op). + otel.SetTextMapPropagator(propagation.TraceContext{}) + + // Handle this error in a sensible manner where possible + defer func() { _ = tracerProvider.Shutdown(ctx) }() + + config := prometheus.Config{} + c := controller.New( + processor.New( + selector.NewWithHistogramDistribution( + histogram.WithExplicitBoundaries(config.DefaultHistogramBoundaries), + ), + export.CumulativeExportKindSelector(), + processor.WithMemory(true), + ), + ) + + exporter, err := prometheus.New(config, c) + if err != nil { + log.Fatal(err) + } + + global.SetMeterProvider(exporter.MeterProvider()) + + http.HandleFunc("/", exporter.ServeHTTP) + go func() { + _ = http.ListenAndServe(":2222", nil) + }() + fmt.Println("Prometheus server running on :2222") + } + if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { @@ -254,7 +321,18 @@ func main() { log.Fatal(err) } - cleanup(ctx) + args := flag.Args() + if len(args) == 0 { + log.Fatal("must enter cleanup or test") + } + + if args[0] == "cleanup" { + cleanup(ctx) + os.Exit(0) + } + if args[0] != "test" { + log.Fatalf("unknown command: %s", args[0]) + } var wg sync.WaitGroup resultChan := make(chan result) diff --git a/example/opentelemetry/docker-compose.yml b/example/opentelemetry/docker-compose.yml new file mode 100644 index 00000000..52ca1e11 --- /dev/null +++ b/example/opentelemetry/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3.6" +services: + jaeger: + image: jaegertracing/all-in-one:latest + ports: + - "16686:16686" + - "14268" + - "14250" + zipkin: + image: openzipkin/zipkin:latest + ports: + - "9411:9411" + prometheus: + container_name: prometheus + image: prom/prometheus:latest + volumes: + - ./prometheus.yaml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + otel: + image: otel/opentelemetry-collector:0.29.0 + command: ["--config=/etc/otel.yaml"] + volumes: + - ./otel.yaml:/etc/otel.yaml + extra_hosts: + - "host.docker.internal:host-gateway" + ports: + - "8888:8888" # Prometheus metrics exposed by the collector + - "8889:8889" # Prometheus exporter metrics + - "13133" # health_check extension + - "4317:4317" # OTLP gRPC receiver + depends_on: + - prometheus + - jaeger + - zipkin + ovsdb: + image: libovsdb/ovs:latest + tty: true + + stress: + depends_on: [ovsdb, otel] + build: + context: ../../ + target: stress + ports: + - "2222:2222" + command: /bin/sh -c "sleep 5 && stress -otlp otel:4317 -inserts 10000 -ovsdb tcp:ovsdb:6640 test" \ No newline at end of file diff --git a/example/opentelemetry/otel.yaml b/example/opentelemetry/otel.yaml new file mode 100644 index 00000000..b98c6e9d --- /dev/null +++ b/example/opentelemetry/otel.yaml @@ -0,0 +1,43 @@ +receivers: + otlp: + protocols: + grpc: + prometheus: + config: + scrape_configs: + - job_name: "stress" + scrape_interval: 1s + scrape_timeout: 1s + static_configs: + - targets: ["stress:2222"] + +exporters: + prometheus: + endpoint: "0.0.0.0:8889" + namespace: stress + + zipkin: + endpoint: "http://zipkin:9411/api/v2/spans" + format: proto + + jaeger: + endpoint: jaeger:14250 + insecure: true + +processors: + batch: + +extensions: + health_check: + +service: + extensions: [health_check] + pipelines: + traces: + receivers: [otlp] + processors: [batch] + exporters: [zipkin, jaeger] + metrics: + receivers: [prometheus] + processors: [batch] + exporters: [prometheus] diff --git a/example/opentelemetry/prometheus.yaml b/example/opentelemetry/prometheus.yaml new file mode 100644 index 00000000..fce7ca9e --- /dev/null +++ b/example/opentelemetry/prometheus.yaml @@ -0,0 +1,6 @@ +scrape_configs: + - job_name: 'otel' + scrape_interval: 1s + static_configs: + - targets: ['otel:8889'] + - targets: ['otel:8888'] diff --git a/example/play_with_ovs/main.go b/example/play_with_ovs/main.go index b4e1bd33..cd48d000 100644 --- a/example/play_with_ovs/main.go +++ b/example/play_with_ovs/main.go @@ -26,8 +26,8 @@ var update chan model.Model var rootUUID string var connection = flag.String("ovsdb", "unix:/var/run/openvswitch/db.sock", "OVSDB connection string") -func play(ovs client.Client) { - go processInput(ovs) +func play(ctx context.Context, ovs client.Client) { + go processInput(ctx, ovs) for model := range update { bridge := model.(*vswitchd.Bridge) if bridge.Name == "stop" { @@ -47,7 +47,7 @@ func play(ovs client.Client) { } } -func createBridge(ovs client.Client, bridgeName string) { +func createBridge(ctx context.Context, ovs client.Client, bridgeName string) { bridge := vswitchd.Bridge{ UUID: "gopher", Name: bridgeName, @@ -80,7 +80,7 @@ func createBridge(ovs client.Client, bridgeName string) { fmt.Println("Bridge Addition Successful : ", reply[0].UUID.GoUUID) } -func processInput(ovs client.Client) { +func processInput(ctx context.Context, ovs client.Client) { for { fmt.Printf("\n Enter a Bridge Name : ") var bridgeName string @@ -88,11 +88,12 @@ func processInput(ovs client.Client) { if bridgeName == "" { continue } - createBridge(ovs, bridgeName) + createBridge(ctx, ovs, bridgeName) } } func main() { + ctx := context.Background() flag.Parse() quit = make(chan bool) update = make(chan model.Model) @@ -107,7 +108,7 @@ func main() { if err != nil { log.Fatal(err) } - err = ovs.Connect(context.Background()) + err = ovs.Connect(ctx) if err != nil { log.Fatal(err) } @@ -134,6 +135,6 @@ func main() { rootUUID = ovs.Cache().Table(ovsTable).Rows()[0] fmt.Println(`Silly game of stopping this app when a Bridge with name "stop" is monitored !`) - go play(ovs) + go play(ctx, ovs) <-quit } diff --git a/go.mod b/go.mod index cc330184..9b9eca85 100644 --- a/go.mod +++ b/go.mod @@ -9,5 +9,13 @@ require ( github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984 github.com/google/uuid v1.2.0 github.com/ory/dockertest/v3 v3.7.0 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 + go.opentelemetry.io/otel v1.0.0-RC1 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1 + go.opentelemetry.io/otel/exporters/prometheus v0.21.0 + go.opentelemetry.io/otel/metric v0.21.0 + go.opentelemetry.io/otel/sdk v1.0.0-RC1 + go.opentelemetry.io/otel/sdk/export/metric v0.21.0 + go.opentelemetry.io/otel/sdk/metric v0.21.0 + google.golang.org/grpc v1.38.0 ) diff --git a/go.sum b/go.sum index 138e05f3..a96e60a2 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,24 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cenk/hub v1.0.1 h1:RBwXNOF4a8KjD8BJ08XqN8KbrqaGiQLDrgvUGJSHuPA= github.com/cenk/hub v1.0.1/go.mod h1:rJM1LNAW0ppT8FMMuPK6c2NP/R2nH/UthtuRySSaf6Y= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= @@ -13,6 +28,12 @@ github.com/cenkalti/hub v1.0.1 h1:UMtjc6dHSaOQTO15SVA50MBIR9zQwvsukQupDrkIRtg= github.com/cenkalti/hub v1.0.1/go.mod h1:tcYwtS3a2d9NO/0xDXVJWx3IedurUjYCqFCmpi0lpHs= github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984 h1:CNwZyGS6KpfaOWbh2yLkSy3rSTUh3jub9CzpFpP6PVQ= github.com/cenkalti/rpc2 v0.0.0-20210604223624-c1acbc6ec984/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= @@ -28,28 +49,90 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394= github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= @@ -58,22 +141,46 @@ github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/ory/dockertest/v3 v3.7.0 h1:Bijzonc69Ont3OU0a3TWKJ1Rzlh3TsDXP1JrTAkSmsM= github.com/ory/dockertest/v3 v3.7.0/go.mod h1:PvCCgnP7AfBZeVrzwiUTjZx/IUXlGLC1zQlUQrLIlUE= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -82,31 +189,89 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc= +go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1 h1:GHKxjc4EDldz8ScMDpiNwX4BAub6wGFUUo5Axm2BimU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1/go.mod h1:FliQjImlo7emZVjixV8nbDMAa4iAkcWTE9zzSEOiEPw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1 h1:ZOQXuxKJ9evGspu3LvbZxx3KOOQvKAPBJVMOfGf1cOM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1/go.mod h1:cDwRc2Jrh5Gku1peGK8p9rRuX/Uq2OtVmLicjlw2WYU= +go.opentelemetry.io/otel/exporters/prometheus v0.21.0 h1:rmwXVGdF3ewdmDn3xczbyZZc3ju/CB5ilYdeknTeJXk= +go.opentelemetry.io/otel/exporters/prometheus v0.21.0/go.mod h1:cDOHiCcfKsQftYsjw1W2ZCDS3QRCZnEoy3VpGHir6jo= +go.opentelemetry.io/otel/internal/metric v0.21.0 h1:gZlIBo5O51hZOOZz8vEcuRx/l5dnADadKfpT70AELoo= +go.opentelemetry.io/otel/internal/metric v0.21.0/go.mod h1:iOfAaY2YycsXfYD4kaRSbLx2LKmfpKObWBEv9QK5zFo= +go.opentelemetry.io/otel/metric v0.21.0 h1:ZtcJlHqVE4l8Su0WOLOd9fEPheJuYEiQ0wr9wv2p25I= +go.opentelemetry.io/otel/metric v0.21.0/go.mod h1:JWCt1bjivC4iCrz/aCrM1GSw+ZcvY44KCbaeeRhzHnc= +go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk= +go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= +go.opentelemetry.io/otel/sdk v1.0.0-RC1 h1:Sy2VLOOg24bipyC29PhuMXYNJrLsxkie8hyI7kUlG9Q= +go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= +go.opentelemetry.io/otel/sdk/export/metric v0.21.0 h1:4tSMVkDbvrowOeP/6rOfGABEWv5n+0gCfhI/TWleUvc= +go.opentelemetry.io/otel/sdk/export/metric v0.21.0/go.mod h1:gTaOMSQmL4zfsTL47desIPbPla5MyMG29lN3PzcibVg= +go.opentelemetry.io/otel/sdk/metric v0.21.0 h1:LNLUj35NNdEpyJQwj/htiEsfnY6GeTIwYHweCJNV+nc= +go.opentelemetry.io/otel/sdk/metric v0.21.0/go.mod h1:OHOcF8ZjE/L8oL/QXpUFWklPwtaukrfHgoAiPek53rQ= +go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58= +go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= +go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= +go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -116,12 +281,47 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/ovs/start.sh b/ovs/start.sh index d1824f0c..aa43e807 100755 --- a/ovs/start.sh +++ b/ovs/start.sh @@ -8,7 +8,7 @@ ovs_db_version=$(ovsdb-tool schema-version /usr/local/share/openvswitch/vswitch. ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock --remote=ptcp:6640 --pidfile=ovsdb-server.pid & # wait for ovsdb server to start -sleep 0.1 +sleep 2 # begin configuring ovs-vsctl --no-wait -- init diff --git a/server/database.go b/server/database.go index ffb7c0ea..29e91d84 100644 --- a/server/database.go +++ b/server/database.go @@ -1,6 +1,7 @@ package server import ( + "context" "fmt" "sync" @@ -12,12 +13,12 @@ import ( // Database abstracts database operations from ovsdb type Database interface { - CreateDatabase(database string, model *ovsdb.DatabaseSchema) error - Exists(database string) bool - Commit(database string, id uuid.UUID, updates ovsdb.TableUpdates2) error - CheckIndexes(database string, table string, m model.Model) error - List(database, table string, conditions ...ovsdb.Condition) ([]model.Model, error) - Get(database, table string, uuid string) (model.Model, error) + CreateDatabase(ctx context.Context, database string, model *ovsdb.DatabaseSchema) error + Exists(ctx context.Context, database string) bool + Commit(ctx context.Context, database string, id uuid.UUID, updates ovsdb.TableUpdates2) error + CheckIndexes(ctx context.Context, database string, table string, m model.Model) error + List(ctx context.Context, database, table string, conditions ...ovsdb.Condition) ([]model.Model, error) + Get(ctx context.Context, database, table string, uuid string) (model.Model, error) } type inMemoryDatabase struct { @@ -34,7 +35,9 @@ func NewInMemoryDatabase(models map[string]*model.DBModel) Database { } } -func (db *inMemoryDatabase) CreateDatabase(name string, schema *ovsdb.DatabaseSchema) error { +func (db *inMemoryDatabase) CreateDatabase(ctx context.Context, name string, schema *ovsdb.DatabaseSchema) error { + _, span := tracer.Start(ctx, "CreateDatabase") + defer span.End() db.mutex.Lock() defer db.mutex.Unlock() var mo *model.DBModel @@ -50,26 +53,32 @@ func (db *inMemoryDatabase) CreateDatabase(name string, schema *ovsdb.DatabaseSc return nil } -func (db *inMemoryDatabase) Exists(name string) bool { +func (db *inMemoryDatabase) Exists(ctx context.Context, name string) bool { + _, span := tracer.Start(ctx, "Exists") + defer span.End() db.mutex.RLock() defer db.mutex.RUnlock() _, ok := db.databases[name] return ok } -func (db *inMemoryDatabase) Commit(database string, id uuid.UUID, updates ovsdb.TableUpdates2) error { - if !db.Exists(database) { +func (db *inMemoryDatabase) Commit(ctx context.Context, database string, id uuid.UUID, updates ovsdb.TableUpdates2) error { + ctx, span := tracer.Start(ctx, "Commit") + defer span.End() + if !db.Exists(ctx, database) { return fmt.Errorf("db does not exist") } db.mutex.RLock() targetDb := db.databases[database] db.mutex.RLock() - targetDb.Populate2(updates) + targetDb.Populate2(ctx, updates) return nil } -func (db *inMemoryDatabase) CheckIndexes(database string, table string, m model.Model) error { - if !db.Exists(database) { +func (db *inMemoryDatabase) CheckIndexes(ctx context.Context, database string, table string, m model.Model) error { + _, span := tracer.Start(ctx, "CheckIndexes") + defer span.End() + if !db.Exists(ctx, database) { return nil } db.mutex.RLock() @@ -79,8 +88,10 @@ func (db *inMemoryDatabase) CheckIndexes(database string, table string, m model. return targetTable.IndexExists(m) } -func (db *inMemoryDatabase) List(database, table string, conditions ...ovsdb.Condition) ([]model.Model, error) { - if !db.Exists(database) { +func (db *inMemoryDatabase) List(ctx context.Context, database, table string, conditions ...ovsdb.Condition) ([]model.Model, error) { + _, span := tracer.Start(ctx, "List") + defer span.End() + if !db.Exists(ctx, database) { return nil, fmt.Errorf("db does not exist") } db.mutex.RLock() @@ -95,8 +106,10 @@ func (db *inMemoryDatabase) List(database, table string, conditions ...ovsdb.Con return targetTable.RowsByCondition(conditions) } -func (db *inMemoryDatabase) Get(database, table string, uuid string) (model.Model, error) { - if !db.Exists(database) { +func (db *inMemoryDatabase) Get(ctx context.Context, database, table string, uuid string) (model.Model, error) { + _, span := tracer.Start(ctx, "Get") + defer span.End() + if !db.Exists(ctx, database) { return nil, fmt.Errorf("db does not exist") } db.mutex.RLock() diff --git a/server/server.go b/server/server.go index 3450a8ff..ff6d1c17 100644 --- a/server/server.go +++ b/server/server.go @@ -1,6 +1,7 @@ package server import ( + "context" "encoding/json" "fmt" "net" @@ -12,8 +13,11 @@ import ( "github.com/ovn-org/libovsdb/cache" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" + "go.opentelemetry.io/otel" ) +var tracer = otel.Tracer("libovsdb.ovn.org/server") + // OvsdbServer is an ovsdb server type OvsdbServer struct { srv *rpc2.Server @@ -49,7 +53,7 @@ func NewOvsdbServer(db Database, models ...DatabaseModel) (*OvsdbServer, error) } o.modelsMutex.Unlock() for database, model := range o.models { - if err := o.db.CreateDatabase(database, model.Schema); err != nil { + if err := o.db.CreateDatabase(context.Background(), database, model.Schema); err != nil { return nil, err } } @@ -122,6 +126,8 @@ func (o *OvsdbServer) ListDatabases(client *rpc2.Client, args []interface{}, rep func (o *OvsdbServer) GetSchema(client *rpc2.Client, args []interface{}, reply *ovsdb.DatabaseSchema, ) error { + _, span := tracer.Start(context.Background(), "GetSchema") + defer span.End() db, ok := args[0].(string) if !ok { return fmt.Errorf("database %v is not a string", args[0]) @@ -154,6 +160,8 @@ func NewTransaction(schema *ovsdb.DatabaseSchema, model *model.DBModel) Transact // Transact issues a new database transaction and returns the results func (o *OvsdbServer) Transact(client *rpc2.Client, args []json.RawMessage, reply *[]ovsdb.OperationResult) error { + ctx, span := tracer.Start(context.Background(), "Transact") + defer span.End() if len(args) < 2 { return fmt.Errorf("not enough args") } @@ -162,7 +170,7 @@ func (o *OvsdbServer) Transact(client *rpc2.Client, args []json.RawMessage, repl if err != nil { return fmt.Errorf("database %v is not a string", args[0]) } - if !o.db.Exists(db) { + if !o.db.Exists(ctx, db) { return fmt.Errorf("db does not exist") } var ops []ovsdb.Operation @@ -194,11 +202,11 @@ func (o *OvsdbServer) Transact(client *rpc2.Client, args []json.RawMessage, repl } ops = append(ops, op) } - response, updates := o.transact(db, ops) + response, updates := o.transact(ctx, db, ops) *reply = response transactionID := uuid.New() o.processMonitors(transactionID, updates) - return o.db.Commit(db, transactionID, updates) + return o.db.Commit(ctx, db, transactionID, updates) } func deepCopy(a ovsdb.TableUpdates) (ovsdb.TableUpdates, error) { @@ -228,11 +236,13 @@ func (o *OvsdbServer) Cancel(client *rpc2.Client, args []interface{}, reply *[]i // Monitor monitors a given database table and provides updates to the client via an RPC callback func (o *OvsdbServer) Monitor(client *rpc2.Client, args []json.RawMessage, reply *ovsdb.TableUpdates) error { + ctx, span := tracer.Start(context.Background(), "Monitor") + defer span.End() var db string if err := json.Unmarshal(args[0], &db); err != nil { return fmt.Errorf("database %v is not a string", args[0]) } - if !o.db.Exists(db) { + if !o.db.Exists(ctx, db) { return fmt.Errorf("db does not exist") } value := string(args[1]) @@ -252,7 +262,7 @@ func (o *OvsdbServer) Monitor(client *rpc2.Client, args []json.RawMessage, reply } tableUpdates := make(ovsdb.TableUpdates) for t, request := range request { - rows := o.Select(db, t, nil, request.Columns) + rows := o.Select(ctx, db, t, nil, request.Columns) for i := range rows.Rows { tu := make(ovsdb.TableUpdate) uuid := rows.Rows[i]["_uuid"].(ovsdb.UUID).GoUUID @@ -269,11 +279,13 @@ func (o *OvsdbServer) Monitor(client *rpc2.Client, args []json.RawMessage, reply // MonitorCond monitors a given database table and provides updates to the client via an RPC callback func (o *OvsdbServer) MonitorCond(client *rpc2.Client, args []json.RawMessage, reply *ovsdb.TableUpdates2) error { + ctx, span := tracer.Start(context.Background(), "MonitorCond") + defer span.End() var db string if err := json.Unmarshal(args[0], &db); err != nil { return fmt.Errorf("database %v is not a string", args[0]) } - if !o.db.Exists(db) { + if !o.db.Exists(ctx, db) { return fmt.Errorf("db does not exist") } value := string(args[1]) @@ -293,7 +305,7 @@ func (o *OvsdbServer) MonitorCond(client *rpc2.Client, args []json.RawMessage, r } tableUpdates := make(ovsdb.TableUpdates2) for t, request := range request { - rows := o.Select(db, t, nil, request.Columns) + rows := o.Select(ctx, db, t, nil, request.Columns) for i := range rows.Rows { tu := make(ovsdb.TableUpdate2) uuid := rows.Rows[i]["_uuid"].(ovsdb.UUID).GoUUID @@ -308,11 +320,13 @@ func (o *OvsdbServer) MonitorCond(client *rpc2.Client, args []json.RawMessage, r // MonitorCondSince monitors a given database table and provides updates to the client via an RPC callback func (o *OvsdbServer) MonitorCondSince(client *rpc2.Client, args []json.RawMessage, reply *ovsdb.MonitorCondSinceReply) error { + ctx, span := tracer.Start(context.Background(), "MonitorCondSince") + defer span.End() var db string if err := json.Unmarshal(args[0], &db); err != nil { return fmt.Errorf("database %v is not a string", args[0]) } - if !o.db.Exists(db) { + if !o.db.Exists(ctx, db) { return fmt.Errorf("db does not exist") } value := string(args[1]) @@ -332,7 +346,7 @@ func (o *OvsdbServer) MonitorCondSince(client *rpc2.Client, args []json.RawMessa } tableUpdates := make(ovsdb.TableUpdates2) for t, request := range request { - rows := o.Select(db, t, nil, request.Columns) + rows := o.Select(ctx, db, t, nil, request.Columns) for i := range rows.Rows { tu := make(ovsdb.TableUpdate2) uuid := rows.Rows[i]["_uuid"].(ovsdb.UUID).GoUUID diff --git a/server/server_integration_test.go b/server/server_integration_test.go index 24a0a934..70f8e6ab 100644 --- a/server/server_integration_test.go +++ b/server/server_integration_test.go @@ -386,7 +386,8 @@ func TestClientServerInsertDuplicate(t *testing.T) { ovs, err := client.NewOVSDBClient(defDB, client.WithEndpoint(fmt.Sprintf("unix:%s", tmpfile))) require.NoError(t, err) - err = ovs.Connect(context.Background()) + ctx := context.Background() + err = ovs.Connect(ctx) require.NoError(t, err) bridgeRow := &bridgeType{ diff --git a/server/server_test.go b/server/server_test.go index 604300d0..2109e8a0 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1,6 +1,7 @@ package server import ( + "context" "encoding/json" "testing" @@ -66,6 +67,7 @@ func TestExpandNamedUUID(t *testing.T) { } func TestOvsdbServerMonitor(t *testing.T) { + ctx := context.Background() defDB, err := model.NewDBModel("Open_vSwitch", map[string]model.Model{ "Open_vSwitch": &ovsType{}, "Bridge": &bridgeType{}}) @@ -97,14 +99,14 @@ func TestOvsdbServerMonitor(t *testing.T) { bazUUID := uuid.NewString() quuxUUID := uuid.NewString() - _, updates := o.Insert("Open_vSwitch", "Bridge", fooUUID, ovsdb.Row{"name": "foo"}) - _, update2 := o.Insert("Open_vSwitch", "Bridge", barUUID, ovsdb.Row{"name": "bar"}) + _, updates := o.Insert(ctx, "Open_vSwitch", "Bridge", fooUUID, ovsdb.Row{"name": "foo"}) + _, update2 := o.Insert(ctx, "Open_vSwitch", "Bridge", barUUID, ovsdb.Row{"name": "bar"}) updates.Merge(update2) - _, update3 := o.Insert("Open_vSwitch", "Bridge", bazUUID, ovsdb.Row{"name": "baz"}) + _, update3 := o.Insert(ctx, "Open_vSwitch", "Bridge", bazUUID, ovsdb.Row{"name": "baz"}) updates.Merge(update3) - _, update4 := o.Insert("Open_vSwitch", "Bridge", quuxUUID, ovsdb.Row{"name": "quux"}) + _, update4 := o.Insert(ctx, "Open_vSwitch", "Bridge", quuxUUID, ovsdb.Row{"name": "quux"}) updates.Merge(update4) - err = o.db.Commit("Open_vSwitch", uuid.New(), updates) + err = o.db.Commit(context.TODO(), "Open_vSwitch", uuid.New(), updates) require.NoError(t, err) db, err := json.Marshal("Open_vSwitch") diff --git a/server/transact.go b/server/transact.go index 27169026..d56ad909 100644 --- a/server/transact.go +++ b/server/transact.go @@ -1,6 +1,7 @@ package server import ( + "context" "fmt" "reflect" @@ -10,34 +11,36 @@ import ( "github.com/ovn-org/libovsdb/ovsdb" ) -func (o *OvsdbServer) transact(name string, operations []ovsdb.Operation) ([]ovsdb.OperationResult, ovsdb.TableUpdates2) { +func (o *OvsdbServer) transact(ctx context.Context, name string, operations []ovsdb.Operation) ([]ovsdb.OperationResult, ovsdb.TableUpdates2) { + ctx, span := tracer.Start(ctx, "transact") + defer span.End() results := []ovsdb.OperationResult{} updates := make(ovsdb.TableUpdates2) for _, op := range operations { switch op.Op { case ovsdb.OperationInsert: - r, tu := o.Insert(name, op.Table, op.UUIDName, op.Row) + r, tu := o.Insert(ctx, name, op.Table, op.UUIDName, op.Row) results = append(results, r) if tu != nil { updates.Merge(tu) } case ovsdb.OperationSelect: - r := o.Select(name, op.Table, op.Where, op.Columns) + r := o.Select(ctx, name, op.Table, op.Where, op.Columns) results = append(results, r) case ovsdb.OperationUpdate: - r, tu := o.Update(name, op.Table, op.Where, op.Row) + r, tu := o.Update(ctx, name, op.Table, op.Where, op.Row) results = append(results, r) if tu != nil { updates.Merge(tu) } case ovsdb.OperationMutate: - r, tu := o.Mutate(name, op.Table, op.Where, op.Mutations) + r, tu := o.Mutate(ctx, name, op.Table, op.Where, op.Mutations) results = append(results, r) if tu != nil { updates.Merge(tu) } case ovsdb.OperationDelete: - r, tu := o.Delete(name, op.Table, op.Where) + r, tu := o.Delete(ctx, name, op.Table, op.Where) results = append(results, r) if tu != nil { updates.Merge(tu) @@ -65,8 +68,10 @@ func (o *OvsdbServer) transact(name string, operations []ovsdb.Operation) ([]ovs return results, updates } -func (o *OvsdbServer) Insert(database string, table string, rowUUID string, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2) { - if !o.db.Exists(database) { +func (o *OvsdbServer) Insert(ctx context.Context, database string, table string, rowUUID string, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2) { + ctx, span := tracer.Start(ctx, "Insert") + defer span.End() + if !o.db.Exists(ctx, database) { return ovsdb.OperationResult{ Error: "database does not exist", }, nil @@ -118,7 +123,7 @@ func (o *OvsdbServer) Insert(database string, table string, rowUUID string, row } // check for index conflicts - if err := o.db.CheckIndexes(database, table, model); err != nil { + if err := o.db.CheckIndexes(ctx, database, table, model); err != nil { if indexExists, ok := err.(*cache.ErrIndexExists); ok { e := ovsdb.ConstraintViolation{} return ovsdb.OperationResult{ @@ -145,8 +150,10 @@ func (o *OvsdbServer) Insert(database string, table string, rowUUID string, row } } -func (o *OvsdbServer) Select(database string, table string, where []ovsdb.Condition, columns []string) ovsdb.OperationResult { - if !o.db.Exists(database) { +func (o *OvsdbServer) Select(ctx context.Context, database string, table string, where []ovsdb.Condition, columns []string) ovsdb.OperationResult { + ctx, span := tracer.Start(ctx, "Select") + defer span.End() + if !o.db.Exists(ctx, database) { return ovsdb.OperationResult{ Error: "database does not exist", } @@ -158,7 +165,7 @@ func (o *OvsdbServer) Select(database string, table string, where []ovsdb.Condit m := mapper.NewMapper(dbModel.Schema) var results []ovsdb.Row - rows, err := o.db.List(database, table, where...) + rows, err := o.db.List(ctx, database, table, where...) if err != nil { panic(err) } @@ -174,8 +181,10 @@ func (o *OvsdbServer) Select(database string, table string, where []ovsdb.Condit } } -func (o *OvsdbServer) Update(database, table string, where []ovsdb.Condition, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2) { - if !o.db.Exists(database) { +func (o *OvsdbServer) Update(ctx context.Context, database, table string, where []ovsdb.Condition, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2) { + ctx, span := tracer.Start(ctx, "Update") + defer span.End() + if !o.db.Exists(ctx, database) { return ovsdb.OperationResult{ Error: "database does not exist", }, nil @@ -187,7 +196,7 @@ func (o *OvsdbServer) Update(database, table string, where []ovsdb.Condition, ro m := mapper.NewMapper(dbModel.Schema) schema := dbModel.Schema.Table(table) tableUpdate := make(ovsdb.TableUpdate2) - rows, err := o.db.List(database, table, where...) + rows, err := o.db.List(ctx, database, table, where...) if err != nil { return ovsdb.OperationResult{ Error: err.Error(), @@ -276,7 +285,7 @@ func (o *OvsdbServer) Update(database, table string, where []ovsdb.Condition, ro } // check for index conflicts - if err := o.db.CheckIndexes(database, table, new); err != nil { + if err := o.db.CheckIndexes(ctx, database, table, new); err != nil { if indexExists, ok := err.(*cache.ErrIndexExists); ok { e := ovsdb.ConstraintViolation{} return ovsdb.OperationResult{ @@ -303,8 +312,10 @@ func (o *OvsdbServer) Update(database, table string, where []ovsdb.Condition, ro } } -func (o *OvsdbServer) Mutate(database, table string, where []ovsdb.Condition, mutations []ovsdb.Mutation) (ovsdb.OperationResult, ovsdb.TableUpdates2) { - if !o.db.Exists(database) { +func (o *OvsdbServer) Mutate(ctx context.Context, database, table string, where []ovsdb.Condition, mutations []ovsdb.Mutation) (ovsdb.OperationResult, ovsdb.TableUpdates2) { + ctx, span := tracer.Start(ctx, "Mutates") + defer span.End() + if !o.db.Exists(ctx, database) { return ovsdb.OperationResult{ Error: "database does not exist", }, nil @@ -318,7 +329,7 @@ func (o *OvsdbServer) Mutate(database, table string, where []ovsdb.Condition, mu tableUpdate := make(ovsdb.TableUpdate2) - rows, err := o.db.List(database, table, where...) + rows, err := o.db.List(ctx, database, table, where...) if err != nil { panic(err) } @@ -411,7 +422,7 @@ func (o *OvsdbServer) Mutate(database, table string, where []ovsdb.Condition, mu } // check indexes - if err := o.db.CheckIndexes(database, table, new); err != nil { + if err := o.db.CheckIndexes(ctx, database, table, new); err != nil { if indexExists, ok := err.(*cache.ErrIndexExists); ok { e := ovsdb.ConstraintViolation{} return ovsdb.OperationResult{ @@ -443,8 +454,10 @@ func (o *OvsdbServer) Mutate(database, table string, where []ovsdb.Condition, mu } } -func (o *OvsdbServer) Delete(database, table string, where []ovsdb.Condition) (ovsdb.OperationResult, ovsdb.TableUpdates2) { - if !o.db.Exists(database) { +func (o *OvsdbServer) Delete(ctx context.Context, database, table string, where []ovsdb.Condition) (ovsdb.OperationResult, ovsdb.TableUpdates2) { + ctx, span := tracer.Start(ctx, "Delete") + defer span.End() + if !o.db.Exists(ctx, database) { return ovsdb.OperationResult{ Error: "database does not exist", }, nil @@ -455,7 +468,7 @@ func (o *OvsdbServer) Delete(database, table string, where []ovsdb.Condition) (o m := mapper.NewMapper(dbModel.Schema) schema := dbModel.Schema.Table(table) tableUpdate := make(ovsdb.TableUpdate2) - rows, err := o.db.List(database, table, where...) + rows, err := o.db.List(ctx, database, table, where...) if err != nil { panic(err) } diff --git a/server/transact_test.go b/server/transact_test.go index 926950d7..b2e6bcca 100644 --- a/server/transact_test.go +++ b/server/transact_test.go @@ -1,6 +1,7 @@ package server import ( + "context" "testing" "github.com/google/uuid" @@ -12,6 +13,7 @@ import ( ) func TestMutateOp(t *testing.T) { + ctx := context.Background() defDB, err := model.NewDBModel("Open_vSwitch", map[string]model.Model{ "Open_vSwitch": &ovsType{}, "Bridge": &bridgeType{}}) @@ -47,19 +49,20 @@ func TestMutateOp(t *testing.T) { bridgeRow, err := m.NewRow("Bridge", &bridge) require.Nil(t, err) - res, updates := o.Insert("Open_vSwitch", "Open_vSwitch", ovsUUID, ovsRow) + res, updates := o.Insert(ctx, "Open_vSwitch", "Open_vSwitch", ovsUUID, ovsRow) _, err = ovsdb.CheckOperationResults([]ovsdb.OperationResult{res}, []ovsdb.Operation{{Op: "insert"}}) require.Nil(t, err) - res, update2 := o.Insert("Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) + res, update2 := o.Insert(ctx, "Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) _, err = ovsdb.CheckOperationResults([]ovsdb.OperationResult{res}, []ovsdb.Operation{{Op: "insert"}}) require.Nil(t, err) updates.Merge(update2) - err = o.db.Commit("Open_vSwitch", uuid.New(), updates) + err = o.db.Commit(context.TODO(), "Open_vSwitch", uuid.New(), updates) require.NoError(t, err) gotResult, gotUpdate := o.Mutate( + ctx, "Open_vSwitch", "Open_vSwitch", []ovsdb.Condition{ @@ -70,7 +73,7 @@ func TestMutateOp(t *testing.T) { }, ) assert.Equal(t, ovsdb.OperationResult{Count: 1}, gotResult) - err = o.db.Commit("Open_vSwitch", uuid.New(), gotUpdate) + err = o.db.Commit(context.TODO(), "Open_vSwitch", uuid.New(), gotUpdate) require.NoError(t, err) bridgeSet, err := ovsdb.NewOvsSet([]ovsdb.UUID{{GoUUID: bridgeUUID}}) @@ -99,6 +102,7 @@ func TestMutateOp(t *testing.T) { keyValueDelete, err := ovsdb.NewOvsMap(map[string]string{"baz": "quux"}) assert.Nil(t, err) gotResult, gotUpdate = o.Mutate( + ctx, "Open_vSwitch", "Bridge", []ovsdb.Condition{ @@ -204,6 +208,7 @@ func TestDiff(t *testing.T) { func TestOvsdbServerInsert(t *testing.T) { t.Skip("need a helper for comparing rows as map elements aren't in same order") + ctx := context.Background() defDB, err := model.NewDBModel("Open_vSwitch", map[string]model.Model{ "Open_vSwitch": &ovsType{}, "Bridge": &bridgeType{}}) @@ -235,15 +240,15 @@ func TestOvsdbServerInsert(t *testing.T) { bridgeRow, err := m.NewRow("Bridge", &bridge) require.Nil(t, err) - res, updates := o.Insert("Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) + res, updates := o.Insert(ctx, "Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) _, err = ovsdb.CheckOperationResults([]ovsdb.OperationResult{res}, []ovsdb.Operation{{Op: "insert"}}) require.NoError(t, err) - err = ovsDB.Commit("Open_vSwitch", uuid.New(), updates) + err = ovsDB.Commit(context.TODO(), "Open_vSwitch", uuid.New(), updates) assert.NoError(t, err) bridge.UUID = bridgeUUID - br, err := o.db.Get("Open_vSwitch", "Bridge", bridgeUUID) + br, err := o.db.Get(context.TODO(), "Open_vSwitch", "Bridge", bridgeUUID) assert.NoError(t, err) assert.Equal(t, &bridge, br) assert.Equal(t, ovsdb.TableUpdates2{ @@ -257,6 +262,7 @@ func TestOvsdbServerInsert(t *testing.T) { } func TestOvsdbServerUpdate(t *testing.T) { + ctx := context.Background() defDB, err := model.NewDBModel("Open_vSwitch", map[string]model.Model{ "Open_vSwitch": &ovsType{}, "Bridge": &bridgeType{}}) @@ -285,11 +291,11 @@ func TestOvsdbServerUpdate(t *testing.T) { bridgeRow, err := m.NewRow("Bridge", &bridge) require.Nil(t, err) - res, updates := o.Insert("Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) + res, updates := o.Insert(ctx, "Open_vSwitch", "Bridge", bridgeUUID, bridgeRow) _, err = ovsdb.CheckOperationResults([]ovsdb.OperationResult{res}, []ovsdb.Operation{{Op: "insert"}}) require.NoError(t, err) - err = ovsDB.Commit("Open_vSwitch", uuid.New(), updates) + err = ovsDB.Commit(context.TODO(), "Open_vSwitch", uuid.New(), updates) assert.NoError(t, err) halloween, _ := ovsdb.NewOvsSet([]string{"halloween"}) @@ -320,6 +326,7 @@ func TestOvsdbServerUpdate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res, updates := o.Update( + ctx, "Open_vSwitch", "Bridge", []ovsdb.Condition{{ Column: "_uuid", Function: ovsdb.ConditionEqual, Value: ovsdb.UUID{GoUUID: bridgeUUID}, @@ -328,7 +335,7 @@ func TestOvsdbServerUpdate(t *testing.T) { require.NoErrorf(t, err, "%+v", errs) bridge.UUID = bridgeUUID - row, err := o.db.Get("Open_vSwitch", "Bridge", bridgeUUID) + row, err := o.db.Get(context.TODO(), "Open_vSwitch", "Bridge", bridgeUUID) assert.NoError(t, err) br := row.(*bridgeType) assert.NotEqual(t, br, bridgeRow)