func AddMigrateTask(taskMeta *MigrateMeta) error { appname := meta.appName zconn := meta.zconn taskspath := "/r3/app/" + appname + "/migrate" exists, _, err := zconn.Exists(taskspath) if err != nil { return err } if !exists { _, err = zconn.Create(taskspath, []byte(""), 0, zookeeper.WorldACL(zookeeper.PermAll)) if err != nil { return err } } //add task to zk taskpath := fmt.Sprintf("%s/%s", taskspath, taskMeta.TaskId) exists, _, err = zconn.Exists(taskpath) if err != nil { return err } if !exists { taskmeta, _ := json.Marshal(taskMeta) _, err = zconn.Create(taskpath, taskmeta, 0, zookeeper.WorldACL(zookeeper.PermAll)) if err != nil { return err } } return nil }
func (sm *ZookeeperServiceManager) createPathsForService(s skynet.ServiceInfo) error { _, err := sm.conn.Create(path.Join("/hosts", s.ServiceAddr.IPAddress), []byte{}, 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { return err } _, err = sm.conn.Create(path.Join("/regions", s.Region), []byte{}, 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { return err } _, err = sm.conn.Create(path.Join("/services", s.Name), []byte{}, 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { return err } _, err = sm.conn.Create(path.Join("/services", s.Name, s.Version), []byte{}, 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { return err } return nil }
func PersistFrameworkID( fwid *mesos.FrameworkID, zkServers []string, zkChroot string, frameworkName string, ) error { c, _, err := zk.Connect(zkServers, RPC_TIMEOUT) if err != nil { return err } defer c.Close() // attempt to create the path _, err = c.Create( zkChroot, []byte(""), 0, zk.WorldACL(zk.PermAll), ) if err != nil && err != zk.ErrNodeExists { return err } // attempt to write framework ID to <path> / <frameworkName> _, err = c.Create(zkChroot+"/"+frameworkName+"_framework_id", []byte(fwid.GetValue()), 0, zk.WorldACL(zk.PermAll)) // TODO(tyler) when err is zk.ErrNodeExists, cross-check value if err != nil { return err } log.Info("Successfully persisted Framework ID to zookeeper.") return nil }
func createPath(path string, data []byte, client *zk.Conn) error { exists, _, err := client.Exists(path) if err != nil { return err } if exists { return nil } name := "/" p := strings.Split(path, "/") for _, v := range p[1 : len(p)-1] { name += v e, _, _ := client.Exists(name) if !e { _, err = client.Create(name, []byte{}, int32(0), zk.WorldACL(zk.PermAll)) if err != nil { return err } } name += "/" } _, err = client.Create(path, data, int32(0), zk.WorldACL(zk.PermAll)) return err }
func (zs *ZKStorage) createZPath(conn *zk.Conn, zpath string) error { _, err := conn.Create(zpath, nil, 0, zk.WorldACL(zk.PermAll)) if err != nil { if zk.ErrNodeExists == err { return nil } else { parent, _ := path.Split(zpath) if len(parent) == 0 { return errors.New("Specified blank path") } err = zs.createZPath(conn, parent[:len(parent)-1]) if err != nil { return err } _, err = conn.Create(zpath, nil, 0, zk.WorldACL(zk.PermAll)) if err == zk.ErrNodeExists { err = nil } } } if zk.ErrNodeExists == err { return nil } else { return err } }
func (adapter *ZookeeperStoreAdapter) createNode(node StoreNode) error { root := path.Dir(node.Key) var err error exists, _, err := adapter.client.Exists(root) if err != nil { return err } if !exists { err = adapter.createNode(StoreNode{ Key: root, Value: []byte{}, TTL: 0, Dir: true, }) if err != nil { return err } } if node.Dir { _, err = adapter.client.Create(node.Key, []byte{}, 0, zk.WorldACL(zk.PermAll)) } else { _, err = adapter.client.Create(node.Key, adapter.encode(node.Value, node.TTL), 0, zk.WorldACL(zk.PermAll)) } if err == zk.ErrNodeExists { err = nil } return err }
// TestPruneActionLogs is a ZK specific unit test func TestPruneActionLogs(t *testing.T) { ctx := context.Background() ts := newTestServer(t, []string{"test"}) defer ts.Close() if err := ts.CreateKeyspace(ctx, "test_keyspace", &topodatapb.Keyspace{}); err != nil { t.Fatalf("CreateKeyspace: %v", err) } actionLogPath := path.Join(zktopo.GlobalKeyspacesPath, "test_keyspace", "actionlog") zkts := ts.(*TestServer).Impl.(*zktopo.Server) if _, err := zk.CreateRecursive(zkts.GetZConn(), actionLogPath+"/0", "first", 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("CreateRecursive(stale): %v", err) } if _, err := zk.CreateRecursive(zkts.GetZConn(), actionLogPath+"/1", "second", 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("CreateRecursive(fresh): %v", err) } if count, err := zkts.PruneActionLogs(actionLogPath, 1); err != nil || count != 1 { t.Fatalf("PruneActionLogs: %v %v", err, count) } actionLogs, _, err := zkts.GetZConn().Children(actionLogPath) if err != nil || len(actionLogs) != 1 || actionLogs[0] != "1" { t.Errorf("PruneActionLogs kept the wrong things: %v %v", err, actionLogs) } }
func createZookeeperPath() error { zkPathCreated := false var data ServerData data.Weight = ssfCfg.Weight _, port, err := net.SplitHostPort(ssfCfg.ListenAddr) if nil != err { return err } localHostName, err = os.Hostname() if nil != err { return err } localHostNamePort = net.JoinHostPort(localHostName, port) data.Addr = localHostNamePort data.ConnectedTime = time.Now().Unix() serverPath := "/" + ssfCfg.ClusterName + "/servers/" + data.Addr zkConn.Create("/"+ssfCfg.ClusterName, nil, 0, zk.WorldACL(zk.PermAll)) zkConn.Create("/"+ssfCfg.ClusterName+"/servers/", nil, 0, zk.WorldACL(zk.PermAll)) zkData, _ := json.Marshal(&data) for !zkPathCreated { _, err := zkConn.Create(serverPath, zkData, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) if nil != err { glog.Errorf("Failed to create zookeeper path:%s with reason:%v", serverPath, err) time.Sleep(1 * time.Second) } else { zkPathCreated = true } } return nil }
func (this *ZookeeperCoordinator) tryRegisterConsumer(Consumerid string, Groupid string, TopicCount TopicsToNumStreams) (err error) { Debugf(this, "Trying to register consumer %s at group %s in Zookeeper", Consumerid, Groupid) registryDir := newZKGroupDirs(this.config.Root, Groupid).ConsumerRegistryDir pathToConsumer := fmt.Sprintf("%s/%s", registryDir, Consumerid) data, mappingError := json.Marshal(&ConsumerInfo{ Version: int16(1), Subscription: TopicCount.GetTopicsToNumStreamsMap(), Pattern: TopicCount.Pattern(), Timestamp: time.Now().Unix() * 1000, }) if mappingError != nil { return mappingError } Debugf(this, "Path: %s", pathToConsumer) _, err = this.zkConn.Create(pathToConsumer, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) if err == zk.ErrNoNode { err = this.createOrUpdatePathParentMayNotExistFailFast(registryDir, make([]byte, 0)) if err != nil { return } _, err = this.zkConn.Create(pathToConsumer, data, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } else if err == zk.ErrNodeExists { var stat *zk.Stat _, stat, err = this.zkConn.Get(pathToConsumer) if err != nil { return } _, err = this.zkConn.Set(pathToConsumer, data, stat.Version) } return }
func (z *ZookeeperCoordinator) createConsumersDir() (err error) { _, err = z.zkClient.zkConn.Create(z.groupPath, make([]byte, 0), 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { logger.Output(1, fmt.Sprintf("path:%v , %v", z.groupPath, err)) return err } _, err = z.zkClient.zkConn.Create(z.groupPath+"/ids", make([]byte, 0), 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { logger.Output(1, fmt.Sprintf("path:%v , %v", z.groupPath+"/ids", err)) return err } _, err = z.zkClient.zkConn.Create(z.groupPath+"/offsets", make([]byte, 0), 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { logger.Output(1, fmt.Sprintf("path:%v , %v", z.groupPath+"/offsets", err)) return err } _, err = z.zkClient.zkConn.Create(z.groupPath+"/owners", make([]byte, 0), 0, zk.WorldACL(zk.PermAll)) if err != nil && err != zk.ErrNodeExists { logger.Output(1, fmt.Sprintf("path:%v , %v", z.groupPath+"/owners", err)) return err } return }
func setUpFakeZk(t *testing.T) { conn = fakezk.NewConn() conn.Create("/zk", nil, 0, zookeeper.WorldACL(zookeeper.PermAll)) conn.Create("/zk/fake", nil, 0, zookeeper.WorldACL(zookeeper.PermAll)) conn.Create("/zk/fake/customrules", nil, 0, zookeeper.WorldACL(zookeeper.PermAll)) conn.Create("/zk/fake/customrules/testrules", []byte("customrule1"), 0, zookeeper.WorldACL(zookeeper.PermAll)) conn.Set("/zk/fake/customrules/testrules", []byte(customRule1), -1) }
// AtomicPut put a value at "key" if the key has not been // modified in the meantime, throws an error if this is the case func (s *Zookeeper) AtomicPut(key string, value []byte, previous *store.KVPair, _ *store.WriteOptions) (bool, *store.KVPair, error) { var lastIndex uint64 if previous != nil { meta, err := s.client.Set(s.normalize(key), value, int32(previous.LastIndex)) if err != nil { // Compare Failed if err == zk.ErrBadVersion { return false, nil, store.ErrKeyModified } return false, nil, err } lastIndex = uint64(meta.Version) } else { // Interpret previous == nil as create operation. _, err := s.client.Create(s.normalize(key), value, 0, zk.WorldACL(zk.PermAll)) if err != nil { // Directory does not exist if err == zk.ErrNoNode { // Create the directory parts := store.SplitKey(strings.TrimSuffix(key, "/")) parts = parts[:len(parts)-1] if err = s.createFullPath(parts, false); err != nil { // Failed to create the directory. return false, nil, err } // Create the node if _, err := s.client.Create(s.normalize(key), value, 0, zk.WorldACL(zk.PermAll)); err != nil { // Node exist error (when previous nil) if err == zk.ErrNodeExists { return false, nil, store.ErrKeyExists } return false, nil, err } } else { // Node Exists error (when previous nil) if err == zk.ErrNodeExists { return false, nil, store.ErrKeyExists } // Unhandled error return false, nil, err } } lastIndex = 0 // Newly created nodes have version 0. } pair := &store.KVPair{ Key: key, Value: value, LastIndex: lastIndex, } return true, pair, nil }
func Create(node string, data string, temp bool) (string, error) { ZKConn.Lock() defer ZKConn.Unlock() if temp { return ZKConn.Conn.Create(node, []byte(data), zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) } else { return ZKConn.Conn.Create(node, []byte(data), 0, zk.WorldACL(zk.PermAll)) } }
// UpdateShardReplicationFields is part of the topo.Server interface func (zkts *Server) UpdateShardReplicationFields(ctx context.Context, cell, keyspace, shard string, update func(*topodatapb.ShardReplication) error) error { // create the parent directory to be sure it's here zkDir := path.Join("/zk", cell, "vt", "replication", keyspace) if _, err := zk.CreateRecursive(zkts.zconn, zkDir, nil, 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil && err != zookeeper.ErrNodeExists { return convertError(err) } // now update the data zkPath := shardReplicationPath(cell, keyspace, shard) for { data, stat, err := zkts.zconn.Get(zkPath) var version int32 = -1 sr := &topodatapb.ShardReplication{} switch err { case zookeeper.ErrNoNode: // empty node, version is 0 case nil: version = stat.Version if len(data) > 0 { if err = json.Unmarshal(data, sr); err != nil { return fmt.Errorf("bad ShardReplication data %v", err) } } default: return convertError(err) } err = update(sr) switch err { case topo.ErrNoUpdateNeeded: return nil case nil: // keep going default: return err } // marshall and save d, err := json.MarshalIndent(sr, "", " ") if err != nil { return err } if version == -1 { _, err = zkts.zconn.Create(zkPath, d, 0, zookeeper.WorldACL(zookeeper.PermAll)) if err != zookeeper.ErrNodeExists { return convertError(err) } } else { _, err = zkts.zconn.Set(zkPath, d, version) if err != zookeeper.ErrBadVersion { return convertError(err) } } } }
func CreateOrUpdate(zconn zookeeper.Conn, zkPath, value string, flags int, aclv []zookeeper.ACL, recursive bool) (pathCreated string, err error) { if recursive { pathCreated, err = CreateRecursive(zconn, zkPath, value, 0, zookeeper.WorldACL(zookeeper.PermAll)) } else { pathCreated, err = zconn.Create(zkPath, []byte(value), 0, zookeeper.WorldACL(zookeeper.PermAll)) } if err != nil && ZkErrorEqual(err, zookeeper.ErrNodeExists) { pathCreated = "" _, err = zconn.Set(zkPath, []byte(value), -1) } return }
// CreateOrUpdate creates or updates a file. func CreateOrUpdate(zconn Conn, zkPath string, value []byte, flags int, aclv []zookeeper.ACL, recursive bool) (pathCreated string, err error) { if recursive { pathCreated, err = CreateRecursive(zconn, zkPath, value, 0, zookeeper.WorldACL(zookeeper.PermAll)) } else { pathCreated, err = zconn.Create(zkPath, value, 0, zookeeper.WorldACL(zookeeper.PermAll)) } if err == zookeeper.ErrNodeExists { pathCreated = "" _, err = zconn.Set(zkPath, value, -1) } return }
func zk_reginster(path string, c *zk.Conn) (string, error) { mgo_path := path + "/" + *server_addr //tPath, err := c.Create(mgo_path, []byte{}, 0, zk.WorldACL(zk.PermAll)) tPath, err := c.Create(path, []byte{}, 0, zk.WorldACL(zk.PermAll)) log.Infof("zk_reginster | path :%+v", mgo_path) tPath, err = c.Create(mgo_path, []byte{}, zk.FlagEphemeral|zk.FlagSequence, zk.WorldACL(zk.PermAll)) if err != nil { log.Warnf("zk_reginster | Create returned: %+v", err) } log.Infof("zk_reginster | create :%+v", tPath) return tPath, err }
// newTestServer returns a new TestServer (with the required paths created) func newTestServer(t *testing.T, cells []string) topo.Impl { zconn := fakezk.NewConn() // create the toplevel zk paths if _, err := zk.CreateRecursive(zconn, "/zk/global/vt", nil, 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("cannot init ZooKeeper: %v", err) } for _, cell := range cells { if _, err := zk.CreateRecursive(zconn, fmt.Sprintf("/zk/%v/vt", cell), nil, 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("cannot init ZooKeeper: %v", err) } } return &TestServer{Impl: zktopo.NewServer(zconn), localCells: cells} }
// zkData create zookeeper path, if path exists ignore error, and set node data. func zkData(conn *zk.Conn, redisMaster string) error { node := path.Join(conf.ZKPath, conf.Node) tpath := "" for _, str := range strings.Split(conf.ZKPath, "/")[1:] { tpath = path.Join(tpath, "/", str) log.Info("create zookeeper path: \"%s\"", tpath) _, err := conn.Create(tpath, []byte(""), 0, zk.WorldACL(zk.PermAll)) if err != nil { if err == zk.ErrNodeExists { log.Warn("zk.create(\"%s\") exists", tpath) } else { log.Error("zk.create(\"%s\") error(%v)", tpath, err) return err } } } if _, err := conn.Create(node, []byte{}, 0, zk.WorldACL(zk.PermAll)); err != nil { if err == zk.ErrNodeExists { oData, stat, err := conn.Get(node) if err != nil { log.Error("zk.Get(\"%s\") error(%v)", node, err) return err } ni := unmarshal(oData) if ni != nil || len(ni.Servers) == 0 { log.Warn("node have not data") return nil } data := marshal(ni, redisMaster) if len(data) == 0 { log.Warn("marshal error") return nil } if bytes.Equal(oData, data) { log.Warn("zk data same, no change") return nil } if _, err = conn.Set(node, data, stat.Version); err != nil { log.Error("zk.Set(\"%s\", data, 0) error(%v)", node, err) return err } log.Info("zk update data: \"%s\"", node) } else { log.Error("zk.create(\"%s\") error(%v)", tpath, err) return err } } return nil }
func main() { conn := connect() defer conn.Close() flags := int32(0) acl := zk.WorldACL(zk.PermAll) _, err := conn.Create("/dir", []byte("data-parent"), flags, acl) must(err) for i := 1; i <= 3; i++ { key := fmt.Sprintf("/dir/key%d", i) data := []byte(fmt.Sprintf("data-child-%d", i)) path, err := conn.Create(key, data, flags, acl) must(err) fmt.Printf("%+v\n", path) } data, _, err := conn.Get("/dir") fmt.Printf("/dir: %s\n", string(data)) children, _, err := conn.Children("/dir") must(err) for _, name := range children { data, _, err := conn.Get("/dir/" + name) must(err) fmt.Printf("/dir/%s: %s\n", name, string(data)) err = conn.Delete("/dir/"+name, 0) } err = conn.Delete("/dir", 0) must(err) }
func TestChildren(t *testing.T) { conn := NewConn() defer conn.Close() nodes := []string{"/zk", "/zk/foo", "/zk/bar"} wantChildren := []string{"bar", "foo"} for _, path := range nodes { if _, err := conn.Create(path, nil, 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("conn.Create: %v", err) } } children, _, err := conn.Children("/zk") if err != nil { t.Fatalf(`conn.Children("/zk"): %v`, err) } sort.Strings(children) if length := len(children); length != 2 { t.Errorf("children: got %v, wanted %v", children, wantChildren) } for i, path := range children { if wantChildren[i] != path { t.Errorf("children: got %v, wanted %v", children, wantChildren) break } } }
func (this *Create) Run(args []string) (exitCode int) { cmdFlags := flag.NewFlagSet("create", flag.ContinueOnError) cmdFlags.Usage = func() { this.Ui.Output(this.Help()) } cmdFlags.StringVar(&this.zone, "z", ctx.ZkDefaultZone(), "") cmdFlags.StringVar(&this.path, "p", "", "") if err := cmdFlags.Parse(args); err != nil { return 1 } if validateArgs(this, this.Ui). require("-p"). requireAdminRights("-p"). invalid(args) { return 2 } if this.zone == "" { this.Ui.Error("unknown zone") return 2 } zkzone := gzk.NewZkZone(gzk.DefaultConfig(this.zone, ctx.ZoneZkAddrs(this.zone))) defer zkzone.Close() conn := zkzone.Conn() data := inData() flags := int32(0) acl := zk.WorldACL(zk.PermAll) _, err := conn.Create(this.path, data, flags, acl) must(err) return }
// AddVolume add a volume data in zk. func (z *Zookeeper) AddVolume(v *Volume) (err error) { var vpath = z.volumePath(v.Id) if _, err = z.c.Create(vpath, v.Meta(), 0, zk.WorldACL(zk.PermAll)); err != nil { log.Errorf("zk.Create(\"%s\") error(%v)", vpath, err) } return }
// ensurePath is used to create each node in the path hierarchy. // We avoid calling this optimistically, and invoke it when we get // an error during an operation func (c *ZookeeperBackend) ensurePath(path string, value []byte) error { nodes := strings.Split(path, "/") acl := zk.WorldACL(zk.PermAll) fullPath := "" for index, node := range nodes { if strings.TrimSpace(node) != "" { fullPath += "/" + node isLastNode := index+1 == len(nodes) // set parent nodes to nil, leaf to value // this block reduces round trips by being smart on the leaf create/set if exists, _, _ := c.client.Exists(fullPath); !isLastNode && !exists { if _, err := c.client.Create(fullPath, nil, int32(0), acl); err != nil { return err } } else if isLastNode && !exists { if _, err := c.client.Create(fullPath, value, int32(0), acl); err != nil { return err } } else if isLastNode && exists { if _, err := c.client.Set(fullPath, value, int32(-1)); err != nil { return err } } } } return nil }
func (i *ZookeeperHALock) attemptLock(lockpath string, didLock chan struct{}, failLock chan error, releaseCh chan bool) { // Wait to acquire the lock in ZK acl := zk.WorldACL(zk.PermAll) lock := zk.NewLock(i.in.client, lockpath, acl) err := lock.Lock() if err != nil { failLock <- err return } // Set node value data := []byte(i.value) err = i.in.ensurePath(lockpath, data) if err != nil { failLock <- err lock.Unlock() return } i.zkLock = lock // Signal that lock is held close(didLock) // Handle an early abort release := <-releaseCh if release { lock.Unlock() } }
// CreateKeyspace is part of the topo.Server interface func (zkts *Server) CreateKeyspace(ctx context.Context, keyspace string, value *topodatapb.Keyspace) error { keyspacePath := path.Join(GlobalKeyspacesPath, keyspace) pathList := []string{ keyspacePath, path.Join(keyspacePath, "action"), path.Join(keyspacePath, "actionlog"), path.Join(keyspacePath, "shards"), } data, err := json.MarshalIndent(value, "", " ") if err != nil { return err } alreadyExists := false for i, zkPath := range pathList { var c []byte if i == 0 { c = data } _, err := zk.CreateRecursive(zkts.zconn, zkPath, c, 0, zookeeper.WorldACL(zookeeper.PermAll)) switch err { case nil: // nothing here case zookeeper.ErrNodeExists: alreadyExists = true default: return convertError(err) } } if alreadyExists { return topo.ErrNodeExists } return nil }
// TestPurgeActions is a ZK specific unit test func TestPurgeActions(t *testing.T) { ctx := context.Background() ts := newTestServer(t, []string{"test"}) defer ts.Close() if err := ts.CreateKeyspace(ctx, "test_keyspace", &topodatapb.Keyspace{}); err != nil { t.Fatalf("CreateKeyspace: %v", err) } actionPath := path.Join(zktopo.GlobalKeyspacesPath, "test_keyspace", "action") zkts := ts.(*TestServer).Impl.(*zktopo.Server) if _, err := zk.CreateRecursive(zkts.GetZConn(), actionPath+"/topurge", "purgeme", 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("CreateRecursive(topurge): %v", err) } if _, err := zk.CreateRecursive(zkts.GetZConn(), actionPath+"/tokeep", "keepme", 0, zookeeper.WorldACL(zookeeper.PermAll)); err != nil { t.Fatalf("CreateRecursive(tokeep): %v", err) } if err := zkts.PurgeActions(actionPath, func(data string) bool { return data == "purgeme" }); err != nil { t.Fatalf("PurgeActions(tokeep): %v", err) } actions, _, err := zkts.GetZConn().Children(actionPath) if err != nil || len(actions) != 1 || actions[0] != "tokeep" { t.Errorf("PurgeActions kept the wrong things: %v %v", err, actions) } }
func AddApp(appName string, config []byte) error { zconn, _, err := meta.DialZk(ZkAddr) defer func() { if zconn != nil { zconn.Close() } }() if err != nil { return fmt.Errorf("zk: can't connect: %v", err) } zkPath := "/r3/app/" + appName exists, _, err := zconn.Exists(zkPath) if err != nil { return fmt.Errorf("zk: call exist failed %v", err) } if exists { return fmt.Errorf("zk: %s node already exists", appName) } else { //add node _, err := zconn.Create(zkPath, config, 0, zookeeper.WorldACL(zookeeper.PermAll)) if err != nil { return fmt.Errorf("zk: create failed %v", err) } return nil } }
func TestZookeeperBackend(t *testing.T) { addr := os.Getenv("ZOOKEEPER_ADDR") if addr == "" { t.SkipNow() } client, _, err := zk.Connect([]string{addr}, time.Second) if err != nil { t.Fatalf("err: %v", err) } randPath := fmt.Sprintf("/vault-%d", time.Now().Unix()) acl := zk.WorldACL(zk.PermAll) _, err = client.Create(randPath, []byte("hi"), int32(0), acl) if err != nil { t.Fatalf("err: %v", err) } defer func() { client.Delete(randPath, -1) }() b, err := NewBackend("zookeeper", map[string]string{ "address": addr + "," + addr, "path": randPath, }) if err != nil { t.Fatalf("err: %s", err) } testBackend(t, b) testBackend_ListPrefix(t, b) }
func DeleteRecursive(zconn zookeeper.Conn, zkPath string, version int) error { // version: -1 delete any version of the node at path - only applies to the top node err := zconn.Delete(zkPath, int32(version)) if err == nil { return nil } if !ZkErrorEqual(err, zookeeper.ErrNotEmpty) { return err } // Remove the ability for other nodes to get created while we are trying to delete. // Otherwise, you can enter a race condition, or get starved out from deleting. _, err = zconn.SetACL(zkPath, zookeeper.WorldACL(zookeeper.PermAdmin|zookeeper.PermDelete|zookeeper.PermRead), int32(version)) if err != nil { return err } children, _, err := zconn.Children(zkPath) if err != nil { return err } for _, child := range children { err := DeleteRecursive(zconn, path.Join(zkPath, child), -1) if err != nil && !ZkErrorEqual(err, zookeeper.ErrNoNode) { return fmt.Errorf("zkutil: recursive delete failed: %v", err) } } err = zconn.Delete(zkPath, int32(version)) if err != nil && !ZkErrorEqual(err, zookeeper.ErrNotEmpty) { err = fmt.Errorf("zkutil: nodes getting recreated underneath delete (app race condition): %v", zkPath) } return err }