From 058355d93061f6e63c8df74cd8087fb34c8efa83 Mon Sep 17 00:00:00 2001 From: kristopher watts Date: Sat, 9 Jan 2021 14:06:25 -0700 Subject: [PATCH] Fixing issue 53: https://github.com/gopher-net/docker-ovs-plugin/issues/53 --- .gitignore | 3 ++ Dockerfile | 11 ++--- build.sh | 3 ++ go.mod | 18 +++++++ go.sum | 22 +++++++++ ovs/ovs_port.go | 23 ++++----- ovs/ovsdb.go | 122 +++++++++++++++++++++++++++++++++++++----------- 7 files changed, 157 insertions(+), 45 deletions(-) create mode 100644 build.sh create mode 100644 go.mod create mode 100644 go.sum diff --git a/.gitignore b/.gitignore index 5d89f38..527f0d1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,6 @@ _testmain.go *.prof .idea plugin + +docker-ovs-plugin +docker-ovs-plugin.exe diff --git a/Dockerfile b/Dockerfile index a5e041c..33a194c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,4 @@ -FROM golang -RUN apt-get update && apt-get -y install iptables dbus -RUN go get github.com/tools/godep -COPY . /go/src/github.com/gopher-net/docker-ovs-plugin -WORKDIR /go/src/github.com/gopher-net/docker-ovs-plugin -RUN godep go install -v -ENTRYPOINT ["docker-ovs-plugin"] +FROM busybox +COPY docker-ovs-plugin / +WORKDIR / +ENTRYPOINT ["/docker-ovs-plugin"] diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..ef0f342 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash +CGO_ENABLED=0 go build +docker build -t gophernet/ovs-plugin . diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..cf30af6 --- /dev/null +++ b/go.mod @@ -0,0 +1,18 @@ +module github.com/gopher-net/docker-ovs-plugin + +go 1.15 + +require ( + github.com/Sirupsen/logrus v0.8.7 + github.com/cenkalti/hub v1.0.1-0.20150602151022-57d753b5f485 + github.com/cenkalti/rpc2 v0.0.0-20150604075418-2d1be381ce47 + github.com/codegangsta/cli v1.2.0 + github.com/docker/docker v1.9.1 + github.com/docker/libnetwork v0.0.0-20151125234013-04cc1fa0a89f + github.com/godbus/dbus v0.0.0-20151119164108-9055aba822f5 + github.com/gopher-net/dknet v0.0.0-20151128012059-72c72f2ceb6e + github.com/opencontainers/runc v0.0.6-0.20151124230036-36015470c2c3 + github.com/samalba/dockerclient v0.0.0-20151110192645-82381805d353 + github.com/socketplane/libovsdb v0.0.0-20150219002516-58cf01279880 + github.com/vishvananda/netlink v0.0.0-20151117192157-a57a12c1b1d8 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..bdc051b --- /dev/null +++ b/go.sum @@ -0,0 +1,22 @@ +github.com/Sirupsen/logrus v0.8.7 h1:hGa+d4KZNNNDmzAj6vlkeOQsgjrh8zg4EXB81mWoTm4= +github.com/Sirupsen/logrus v0.8.7/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U= +github.com/cenkalti/hub v1.0.1-0.20150602151022-57d753b5f485/go.mod h1:tcYwtS3a2d9NO/0xDXVJWx3IedurUjYCqFCmpi0lpHs= +github.com/cenkalti/rpc2 v0.0.0-20150604075418-2d1be381ce47/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= +github.com/codegangsta/cli v1.2.0 h1:9+1VK9V1gv4mUd1oDyTcM8UDDlbj2KPFsYdNluIElvM= +github.com/codegangsta/cli v1.2.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA= +github.com/docker/docker v1.9.1 h1:2a6ur8Gs2Ev2oRm7PIExQTDFcOXASgM0JebuO636FlQ= +github.com/docker/docker v1.9.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/libnetwork v0.0.0-20151125234013-04cc1fa0a89f h1:bAQpwhwVo48z0UCvMzYwuOzL9FA8HFJ+zE7PvVy/HK8= +github.com/docker/libnetwork v0.0.0-20151125234013-04cc1fa0a89f/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8= +github.com/godbus/dbus v0.0.0-20151119164108-9055aba822f5 h1:JI9CsWYricnxhaEdp9QNap2wrHXVL/62Qes2KcaXGQE= +github.com/godbus/dbus v0.0.0-20151119164108-9055aba822f5/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/gopher-net/dknet v0.0.0-20151128012059-72c72f2ceb6e h1:NaTQEG5CpWjpH7Gtz6F0Zo6RNpGaPR8vZjbENrtWuY8= +github.com/gopher-net/dknet v0.0.0-20151128012059-72c72f2ceb6e/go.mod h1:tew7QF8yLi2/tCJAUA1pr2ID/6IKJihRFfWLKjgudvs= +github.com/opencontainers/runc v0.0.6-0.20151124230036-36015470c2c3 h1:oX5Vmg7TPO9rZUk9SKmqe8feOnSynlCt2R52D18LA+k= +github.com/opencontainers/runc v0.0.6-0.20151124230036-36015470c2c3/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/samalba/dockerclient v0.0.0-20151110192645-82381805d353 h1:oYCO+xvc5O3Vbcf0QoyI2LxBwhoAIFXdURSza3elN5U= +github.com/samalba/dockerclient v0.0.0-20151110192645-82381805d353/go.mod h1:yeYR4SlaRZJct6lwNRKR+qd0CocnxxWDE7Vh5dxsn/w= +github.com/socketplane/libovsdb v0.0.0-20150219002516-58cf01279880 h1:hJWrrvrR9Ipsw8skWD7OrWic/wkva5reUHT0VmjvDcA= +github.com/socketplane/libovsdb v0.0.0-20150219002516-58cf01279880/go.mod h1:wIN7DIpadYHC4aX3+I8xH72uWy71dw3YpTiHvQh3yHg= +github.com/vishvananda/netlink v0.0.0-20151117192157-a57a12c1b1d8 h1:aUHY3lxZ7hgddpYwqy/zee8GXAoPyYztimwWKRZESvQ= +github.com/vishvananda/netlink v0.0.0-20151117192157-a57a12c1b1d8/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= diff --git a/ovs/ovs_port.go b/ovs/ovs_port.go index d3a930d..b200af6 100644 --- a/ovs/ovs_port.go +++ b/ovs/ovs_port.go @@ -240,22 +240,23 @@ func (ovsdber *ovsdber) addOvsVethPort(bridgeName string, portName string, tag u } for i, o := range reply { if o.Error != "" && i < len(operations) { - msg := fmt.Sprintf("Transaction Failed due to an error ]", o.Error, " details:", o.Details, " in ", operations[i]) - return errors.New(msg) + return fmt.Errorf("Transaction Failed due to an error ] %v details: %v in %v", o.Error, o.Details, operations[i]) } else if o.Error != "" { - msg := fmt.Sprintf("Transaction Failed due to an error :", o.Error) - return errors.New(msg) + return fmt.Errorf("Transaction Failed due to an error: %v", o.Error) } } return nil } -func portUUIDForName(portName string) string { - portCache := ovsdbCache["Port"] - for key, val := range portCache { - if val.Fields["name"] == portName { - return key +func portUUIDForName(portName string) (r string) { + ovsdbCache.tableCache(`Port`, func(portCache map[string]libovsdb.Row) { + for key, val := range portCache { + if val.Fields["name"] == portName { + r = key + break + } } - } - return "" + return + }) + return } diff --git a/ovs/ovsdb.go b/ovs/ovsdb.go index a458d08..4e21554 100644 --- a/ovs/ovsdb.go +++ b/ovs/ovsdb.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "reflect" + "sync" "time" log "github.com/Sirupsen/logrus" @@ -21,10 +22,20 @@ const ( var ( quit chan bool update chan *libovsdb.TableUpdates - ovsdbCache map[string]map[string]libovsdb.Row - contextCache map[string]string + ovsdbCache *dbCache + contextCache *ctxCache ) +type dbCache struct { + sync.Mutex + cache map[string]map[string]libovsdb.Row +} + +type ctxCache struct { + sync.Mutex + cache map[string]string +} + type ovsdber struct { ovsdb *libovsdb.OvsdbClient } @@ -48,7 +59,12 @@ func (o OvsdbNotifier) Echo([]interface{}) { func (ovsdber *ovsdber) initDBCache() { quit = make(chan bool) update = make(chan *libovsdb.TableUpdates) - ovsdbCache = make(map[string]map[string]libovsdb.Row) + ovsdbCache = &dbCache{ + cache: make(map[string]map[string]libovsdb.Row), + } + contextCache = &ctxCache{ + cache: make(map[string]string), + } // Register for ovsdb table notifications var notifier OvsdbNotifier @@ -59,7 +75,6 @@ func (ovsdber *ovsdber) initDBCache() { log.Errorf("Error populating initial OVSDB cache: %s", err) } populateCache(*initCache) - contextCache = make(map[string]string) populateContextCache(ovsdber.ovsdb) // async monitoring of the ovs bridge(s) for table updates @@ -73,22 +88,19 @@ func populateContextCache(ovs *libovsdb.OvsdbClient) { if ovs == nil { return } - tableCache := getTableCache("Interface") - for _, row := range tableCache { - config, ok := row.Fields["other_config"] - ovsMap := config.(libovsdb.OvsMap) - otherConfig := map[interface{}]interface{}(ovsMap.GoMap) - if ok { - containerID, ok := otherConfig[contextKey] + ovsdbCache.tableCache(`Interface`, func(tableCache map[string]libovsdb.Row) { + for _, row := range tableCache { + config, ok := row.Fields["other_config"] + ovsMap := config.(libovsdb.OvsMap) + otherConfig := map[interface{}]interface{}(ovsMap.GoMap) if ok { - contextCache[containerID.(string)] = otherConfig[contextValue].(string) + containerID, ok := otherConfig[contextKey] + if ok { + contextCache.put(containerID.(string), otherConfig[contextValue].(string)) + } } } - } -} - -func getTableCache(tableName string) map[string]libovsdb.Row { - return ovsdbCache[tableName] + }) } func (ovsdber *ovsdber) portExists(portName string) (bool, error) { @@ -138,25 +150,81 @@ func (ovsdber *ovsdber) monitorBridges() { } } -func (ovsdber *ovsdber) getRootUUID() string { - for uuid := range ovsdbCache["Open_vSwitch"] { - return uuid - } - return "" +func (ovsdber *ovsdber) getRootUUID() (r string) { + ovsdbCache.tableCache(`Open_vSwitch`, func(mp map[string]libovsdb.Row) { + for uuid := range mp { + r = uuid + return + } + }) + return } func populateCache(updates libovsdb.TableUpdates) { for table, tableUpdate := range updates.Updates { - if _, ok := ovsdbCache[table]; !ok { - ovsdbCache[table] = make(map[string]libovsdb.Row) - } + ovsdbCache.initTable(table) for uuid, row := range tableUpdate.Rows { empty := libovsdb.Row{} if !reflect.DeepEqual(row.New, empty) { - ovsdbCache[table][uuid] = row.New + ovsdbCache.addTableRow(table, uuid, row.New) } else { - delete(ovsdbCache[table], uuid) + ovsdbCache.deleteTableRow(table, uuid) } } } } + +type rowfunc func(map[string]libovsdb.Row) + +func (dbc *dbCache) tableCache(table string, rf rowfunc) { + dbc.Lock() + rf(dbc.cache[table]) + dbc.Unlock() +} + +func (dbc *dbCache) initTable(key string) (added bool) { + dbc.Lock() + if _, ok := dbc.cache[key]; !ok { + dbc.cache[key] = make(map[string]libovsdb.Row) + added = true + } + dbc.Unlock() + return +} + +func (dbc *dbCache) addTableRow(table, uuid string, row libovsdb.Row) { + dbc.Lock() + tbl, ok := dbc.cache[table] + if !ok { + tbl = make(map[string]libovsdb.Row) + } + tbl[uuid] = row + dbc.cache[table] = tbl + dbc.Unlock() +} + +func (dbc *dbCache) deleteTableRow(table, uuid string) { + dbc.Lock() + if tbl, ok := dbc.cache[table]; ok { + delete(tbl, uuid) + dbc.cache[table] = tbl + } + dbc.Unlock() +} + +func (c *ctxCache) get(k string) (r string) { + c.Lock() + if c != nil && c.cache != nil { + r = c.cache[k] + } + c.Unlock() + return `` +} + +func (c *ctxCache) put(k, v string) { + c.Lock() + if c != nil && c.cache != nil { + c.cache[k] = v + } + c.Unlock() +}