func CreateProxyInfo(zkConn zkhelper.Conn, productName string, pi *ProxyInfo) (string, error) { data, err := json.Marshal(pi) if err != nil { return "", errors.Trace(err) } dir := GetProxyPath(productName) zkhelper.CreateRecursive(zkConn, dir, "", 0, zkhelper.DefaultDirACLs()) return zkConn.Create(path.Join(dir, pi.Id), data, zk.FlagEphemeral, zkhelper.DefaultFileACLs()) }
func doResponseForTest(conn zkhelper.Conn, seq string, pi *ProxyInfo) error { actionPath := GetActionResponsePath(productName) + "/" + seq data, err := json.Marshal(pi) if err != nil { return errors.Trace(err) } _, err = conn.Create(path.Join(actionPath, pi.Id), data, 0, zkhelper.DefaultFileACLs()) return err }
func CreateOrUpdate(zconn zkhelper.Conn, zkPath, value string, flags int, aclv []topo.ACL, recursive bool) (pathCreated string, err error) { if recursive { pathCreated, err = CreateRecursive(zconn, zkPath, value, flags, aclv) } else { pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) } if err != nil && zkhelper.ZkErrorEqual(err, topo.ErrNodeExists) { pathCreated = "" _, err = zconn.Set(zkPath, []byte(value), -1) } return }
// Create a path and any pieces required, think mkdir -p. // Intermediate znodes are always created empty. func CreateRecursive(zconn zkhelper.Conn, zkPath, value string, flags int, aclv []topo.ACL) (pathCreated string, err error) { parts := strings.Split(zkPath, "/") if parts[1] != zkhelper.MagicPrefix { return "", fmt.Errorf("zkutil: non /%v path: %v", zkhelper.MagicPrefix, zkPath) } pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) if zkhelper.ZkErrorEqual(err, topo.ErrNoNode) { // Make sure that nodes are either "file" or "directory" to mirror file system // semantics. dirAclv := make([]topo.ACL, len(aclv)) for i, acl := range aclv { dirAclv[i] = acl dirAclv[i].Perms = zkhelper.PERM_DIRECTORY } _, err = CreateRecursive(zconn, os_path.Dir(zkPath), "", 0, dirAclv) if err != nil && !zkhelper.ZkErrorEqual(err, topo.ErrNodeExists) { return "", err } pathCreated, err = zconn.Create(zkPath, []byte(value), int32(flags), aclv) } return }
func NewActionWithTimeout(zkConn zkhelper.Conn, productName string, actionType ActionType, target interface{}, desc string, needConfirm bool, timeoutInMs int) error { ts := strconv.FormatInt(time.Now().Unix(), 10) action := &Action{ Type: actionType, Desc: desc, Target: target, Ts: ts, } // set action receivers proxies, err := ProxyList(zkConn, productName, func(p *ProxyInfo) bool { return p.State == PROXY_STATE_ONLINE }) if err != nil { return errors.Trace(err) } if needConfirm { // do fencing here, make sure 'offline' proxies are really offline // now we only check whether the proxy lists are match fenceProxies, err := GetFenceProxyMap(zkConn, productName) if err != nil { return errors.Trace(err) } for _, proxy := range proxies { delete(fenceProxies, proxy.Addr) } if len(fenceProxies) > 0 { errMsg := bytes.NewBufferString("Some proxies may not stop cleanly:") for k, _ := range fenceProxies { errMsg.WriteString(" ") errMsg.WriteString(k) } return errors.Errorf("%s", errMsg) } } for _, p := range proxies { buf, err := json.Marshal(p) if err != nil { return errors.Trace(err) } action.Receivers = append(action.Receivers, string(buf)) } b, _ := json.Marshal(action) prefix := GetWatchActionPath(productName) //action root path err = CreateActionRootPath(zkConn, prefix) if err != nil { return errors.Trace(err) } //response path respPath := path.Join(path.Dir(prefix), "ActionResponse") err = CreateActionRootPath(zkConn, respPath) if err != nil { return errors.Trace(err) } //create response node, etcd do not support create in order directory //get path first actionRespPath, err := zkConn.Create(respPath+"/", b, int32(zk.FlagSequence), zkhelper.DefaultFileACLs()) if err != nil { log.ErrorErrorf(err, "zk create resp node = %s", respPath) return errors.Trace(err) } //remove file then create directory zkConn.Delete(actionRespPath, -1) actionRespPath, err = zkConn.Create(actionRespPath, b, 0, zkhelper.DefaultDirACLs()) if err != nil { log.ErrorErrorf(err, "zk create resp node = %s", respPath) return errors.Trace(err) } suffix := path.Base(actionRespPath) // create action node actionPath := path.Join(prefix, suffix) _, err = zkConn.Create(actionPath, b, 0, zkhelper.DefaultFileACLs()) if err != nil { log.ErrorErrorf(err, "zk create action path = %s", actionPath) return errors.Trace(err) } if needConfirm { if err := WaitForReceiverWithTimeout(zkConn, productName, actionRespPath, proxies, timeoutInMs); err != nil { return errors.Trace(err) } } return nil }