func (c *client) Expose() error { output, err := exec.Command("weave", "--local", "ps", "weave:expose").Output() if err != nil { return err } ips := ipMatch.FindAllSubmatch(output, -1) if ips != nil { // Alread exposed! return nil } if err := exec.Command("weave", "expose").Run(); err != nil { return fmt.Errorf("Error running weave expose: %v", err) } return nil }
func (c *client) PS() (map[string]PSEntry, error) { cmd := exec.Command("weave", "--local", "ps") out, err := cmd.StdoutPipe() if err != nil { return nil, err } if err := cmd.Start(); err != nil { return nil, err } defer func() { if err := cmd.Wait(); err != nil { log.Errorf("'weave ps' cmd failed: %v", err) } }() psEntriesByPrefix := map[string]PSEntry{} scanner := bufio.NewScanner(out) for scanner.Scan() { line := scanner.Text() groups := weavePsMatch.FindStringSubmatch(line) if len(groups) == 0 { continue } containerIDPrefix, macAddress, ips := groups[1], groups[2], []string{} for _, ipGroup := range ipMatch.FindAllStringSubmatch(groups[3], -1) { ips = append(ips, ipGroup[1]) } psEntriesByPrefix[containerIDPrefix] = PSEntry{ ContainerIDPrefix: containerIDPrefix, MACAddress: macAddress, IPs: ips, } } if err := scanner.Err(); err != nil { return nil, err } return psEntriesByPrefix, nil }
func (c *conntrackWalker) existingConnections() ([]flow, error) { args := append([]string{"-L", "-o", "xml", "-p", "tcp"}, c.args...) cmd := exec.Command("conntrack", args...) stdout, err := cmd.StdoutPipe() if err != nil { return []flow{}, err } if err := cmd.Start(); err != nil { return []flow{}, err } defer func() { if err := cmd.Wait(); err != nil { log.Errorf("conntrack existingConnections exit error: %v", err) } }() var result conntrack if err := xml.NewDecoder(stdout).Decode(&result); err == io.EOF { return []flow{}, nil } else if err != nil { return []flow{}, err } return result.Flows, nil }
func (c *conntrackWalker) run() { // Fork another conntrack, just to capture existing connections // for which we don't get events existingFlows, err := c.existingConnections() if err != nil { log.Errorf("conntrack existingConnections error: %v", err) return } for _, flow := range existingFlows { c.handleFlow(flow, true) } args := append([]string{"-E", "-o", "xml", "-p", "tcp"}, c.args...) cmd := exec.Command("conntrack", args...) stdout, err := cmd.StdoutPipe() if err != nil { log.Errorf("conntrack error: %v", err) return } stderr, err := cmd.StderrPipe() if err != nil { log.Errorf("conntrack error: %v", err) return } go logPipe("conntrack stderr:", stderr) if err := cmd.Start(); err != nil { log.Errorf("conntrack error: %v", err) return } defer func() { if err := cmd.Wait(); err != nil { log.Errorf("conntrack error: %v", err) } }() c.Lock() // We may have stopped in the mean time, // so check to see if the channel is open // under the lock. select { default: case <-c.quit: return } c.cmd = cmd c.Unlock() // Swallow the first two lines reader := bufio.NewReader(stdout) if line, err := reader.ReadString('\n'); err != nil { log.Errorf("conntrack error: %v", err) return } else if line != xmlHeader { log.Errorf("conntrack invalid output: '%s'", line) return } if line, err := reader.ReadString('\n'); err != nil { log.Errorf("conntrack error: %v", err) return } else if line != conntrackOpenTag { log.Errorf("conntrack invalid output: '%s'", line) return } defer log.Infof("contrack exiting") // Now loop on the output stream decoder := xml.NewDecoder(reader) for { var f flow if err := decoder.Decode(&f); err != nil { log.Errorf("conntrack error: %v", err) return } c.handleFlow(f, false) } }