diff --git a/.gitmodules b/.gitmodules index feedaad8..d03fda92 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ [submodule "vendor/github.com/vishvananda/netns"] path = vendor/github.com/vishvananda/netns url = https://github.com/vishvananda/netns.git +[submodule "vendor/github.com/boltdb/bolt"] + path = vendor/github.com/boltdb/bolt + url = https://github.com/boltdb/bolt diff --git a/Makefile b/Makefile index 6efd5b5a..73072389 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,7 @@ testrunner: $(RUNNER_EXE) $(TEST_TLS_EXE) $(EXES): $(BUILD_UPTODATE) $(WEAVER_EXE) $(WEAVEPROXY_EXE) $(WEAVEUTIL_EXE): common/*.go common/*/*.go net/*.go net/*/*.go -$(WEAVER_EXE): router/*.go ipam/*.go ipam/*/*.go nameserver/*.go prog/weaver/*.go +$(WEAVER_EXE): router/*.go ipam/*.go ipam/*/*.go db/*.go nameserver/*.go prog/weaver/*.go $(WEAVEPROXY_EXE): proxy/*.go prog/weaveproxy/*.go $(WEAVEUTIL_EXE): prog/weaveutil/*.go $(SIGPROXY_EXE): prog/sigproxy/*.go diff --git a/db/boltdb.go b/db/boltdb.go new file mode 100644 index 00000000..0d6b1b86 --- /dev/null +++ b/db/boltdb.go @@ -0,0 +1,81 @@ +package db + +import ( + "bytes" + "encoding/gob" + "fmt" + + "github.com/boltdb/bolt" +) + +type DB interface { + Load(string, interface{}) error + Save(string, interface{}) error +} + +type BoltDB struct { + db *bolt.DB +} + +var ( + versionIdent = []byte("version") + persistenceVersion = []byte{1, 0} // major.minor + topBucket = []byte("top") +) + +func NewBoltDB(dbPathname string) (*BoltDB, error) { + db, err := bolt.Open(dbPathname, 0660, nil) + if err != nil { + return nil, fmt.Errorf("[boltDB] Unable to open %s: %s", dbPathname, err) + } + // check the persistence version + err = db.Update(func(tx *bolt.Tx) error { + if top := tx.Bucket(topBucket); top == nil { + top, err := tx.CreateBucket(topBucket) + if err != nil { + return err + } + if err := top.Put(versionIdent, persistenceVersion); err != nil { + return err + } + } else { + if checkVersion := top.Get(versionIdent); checkVersion != nil { + if checkVersion[0] != persistenceVersion[0] { + return fmt.Errorf("[boltDB] Cannot use persistence file %s - version %x", dbPathname, checkVersion) + } + } + } + return nil + }) + return &BoltDB{db: db}, err +} + +func (d *BoltDB) Load(ident string, data interface{}) error { + return d.db.View(func(tx *bolt.Tx) error { + b := tx.Bucket(topBucket) + v := b.Get([]byte(ident)) + if v == nil { + return nil + } + reader := bytes.NewReader(v) + decoder := gob.NewDecoder(reader) + err := decoder.Decode(data) + return err + }) +} + +func (d *BoltDB) Save(ident string, data interface{}) error { + return d.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket(topBucket) + buf := new(bytes.Buffer) + enc := gob.NewEncoder(buf) + if err := enc.Encode(data); err != nil { + return err + } + return b.Put([]byte(ident), buf.Bytes()) + }) +} + +func (d *BoltDB) Close() error { + return d.db.Close() +} diff --git a/prog/weaver/main.go b/prog/weaver/main.go index 2c1914d1..8fc4a579 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -17,6 +17,7 @@ import ( . "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/common/docker" + "github.com/weaveworks/weave/db" "github.com/weaveworks/weave/ipam" "github.com/weaveworks/weave/nameserver" weavenet "github.com/weaveworks/weave/net" @@ -67,6 +68,7 @@ func main() { dnsConfig dnsConfig datapathName string trustedSubnetStr string + dbPrefix string defaultDockerHost = "unix:///var/run/docker.sock" ) @@ -101,6 +103,7 @@ func main() { mflag.DurationVar(&dnsConfig.ClientTimeout, []string{"-dns-fallback-timeout"}, nameserver.DefaultClientTimeout, "timeout for fallback DNS requests") mflag.StringVar(&dnsConfig.EffectiveListenAddress, []string{"-dns-effective-listen-address"}, "", "address DNS will actually be listening, after Docker port mapping") mflag.StringVar(&datapathName, []string{"-datapath"}, "", "ODP datapath name") + mflag.StringVar(&dbPrefix, []string{"-db-prefix"}, "weave", "pathname/prefix of filename to store data") mflag.StringVar(&trustedSubnetStr, []string{"-trusted-subnets"}, "", "Command separated list of trusted subnets in CIDR notation") @@ -159,6 +162,10 @@ func main() { config.TrustedSubnets = parseTrustedSubnets(trustedSubnetStr) config.PeerDiscovery = !noDiscovery + db, err := db.NewBoltDB(dbPrefix + "data.db") + checkFatal(err) + defer db.Close() + router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay) Log.Println("Our name is", router.Ourself) diff --git a/vendor/github.com/boltdb/bolt b/vendor/github.com/boltdb/bolt new file mode 160000 index 00000000..ee4a0888 --- /dev/null +++ b/vendor/github.com/boltdb/bolt @@ -0,0 +1 @@ +Subproject commit ee4a0888a9abe7eefe5a0992ca4cb06864839873