// fetch returns the anchor files and subdirectories rooted at zdir func fetch(z *zookeeper.Conn, zdir string, children []string) (dirs map[string]struct{}, files map[circuit.WorkerID]*File, err error) { dirs = make(map[string]struct{}) files = make(map[circuit.WorkerID]*File) for _, name := range children { id, err := circuit.ParseWorkerID(name) if err != nil { // Node names that are not files are ok. // We treat them as subdirectories. dirs[name] = struct{}{} continue } znode := path.Join(zdir, name) data, _, err := z.Get(znode) if err != nil { // If this is a Zookeeper connection error, we should bail out log.Printf("Problem getting node `%s` from Zookeeper (%s)", znode, err) continue } zfile := &ZFile{} r := bytes.NewBufferString(data) if err := gob.NewDecoder(r).Decode(zfile); err != nil { log.Printf("anchor file cannot be parsed: (%s)", err) continue } if zfile.Addr.WorkerID() != id { log.Printf("anchor file name vs addr mismatch: %s vs %s\n", id, zfile.Addr.WorkerID()) continue } file := &File{owner: zfile.Addr} files[id] = file } return dirs, files, nil }
func main() { flag.Parse() // Parse WorkerID argument var ( err error id circuit.WorkerID withID bool ) if flag.NArg() == 1 { id, err = circuit.ParseWorkerID(flag.Arg(0)) if err != nil { fmt.Fprintf(os.Stderr, "Problem parsing runtime ID (%s)\n", err) os.Exit(1) } withID = true } else if flag.NArg() != 0 { flag.Usage() } // Read target hosts from standard input var hosts []string buf := bufio.NewReader(os.Stdin) for { line, err := buf.ReadString('\n') if line != "" { line = strings.TrimSpace(line) hosts = append(hosts, line) } if err == io.EOF { break } if err != nil { fmt.Fprintf(os.Stderr, "Problem reading target hosts (%s)", err) os.Exit(1) } } // Log into each host and kill pertinent workers, using POSIX kill for _, h := range hosts { println("Hard-killing circuit worker(s) on", h) var killSh string if withID { killSh = fmt.Sprintf("ps ax | grep -i %s | grep -v grep | awk '{print $1}' | xargs kill -KILL\n", id.String()) } else { killSh = fmt.Sprintf("ps ax | grep -i %s | grep -v grep | awk '{print $1}' | xargs kill -KILL\n", config.Config.Deploy.Worker) } _, stderr, err := posix.Exec("ssh", "", killSh, h, "sh") if err != nil { fmt.Fprintf(os.Stderr, "Problem while killing workers on %s (%s)\n", h, err) fmt.Fprintf(os.Stderr, "Remote shell error output:\n%s\n", stderr) } } }
// Sanitizer ensures that anchor is a valid anchor path in the fs // and returns its parts func Sanitize(anchor string) ([]string, string, error) { anchor = path.Clean(anchor) if len(anchor) == 0 || anchor[0] != '/' { return nil, "", ErrName } parts := strings.Split(anchor[1:], "/") for _, part := range parts { if _, err := circuit.ParseWorkerID(part); err == nil { return nil, "", ErrName } } return parts, "/" + path.Join(parts...), nil }
/* /dir /dir/... /dir/file */ func parse(s string) (anchor string, file, recurse bool, err error) { s = strings.TrimSpace(s) if len(s) == 0 || s[0] != '/' { return "", false, false, circuit.NewError("invalid anchor") } if len(s) > 3 && s[len(s)-3:] == "..." { recurse = true s = s[:len(s)-3] } _, leaf := path.Split(s) if _, err := circuit.ParseWorkerID(leaf); err == nil { return s, true, false, nil } return s, false, recurse, nil }
func (fs *FS) OpenFile(anchor string) (anchorfs.File, error) { ad, af := path.Split(anchor) id, err := circuit.ParseWorkerID(af) if err != nil { return nil, err } dir, err := fs.OpenDir(ad) if err != nil { return nil, err } file, err := dir.OpenFile(id) if err != nil { return nil, err } return file, nil }
func main() { if len(os.Args) != 2 { println("Usage:", os.Args[0], "JailDir") os.Exit(1) } jailDir := os.Args[1] jail, err := os.Open(jailDir) if err != nil { fmt.Fprintf(os.Stderr, "Cannot open jail directory (%s)\n", err) os.Exit(1) } defer jail.Close() fifi, err := jail.Readdir(0) if err != nil { fmt.Fprintf(os.Stderr, "Cannot read jail directory (%s)\n", err) os.Exit(1) } for _, fi := range fifi { if !fi.IsDir() { continue } if _, err := circuit.ParseWorkerID(fi.Name()); err != nil { continue } workerJail := path.Join(jailDir, fi.Name()) println("Clearing", workerJail) l, err := lockfile.Create(path.Join(workerJail, "lock")) if err != nil { // This worker is alive; still holding lock; move on println(err.Error()) continue } l.Release() if err := os.RemoveAll(workerJail); err != nil { fmt.Fprintf(os.Stderr, "Cannot remove worker jail %s (%s)\n", workerJail, err) os.Exit(1) } } }