func (r Responses) compressString(buf io.Writer) { buckets := map[uint64][]*Response{} // Find responses that have the same output by hashing them into buckets for _, v := range r { if v.Error == "" && v.Response != "" { h := fnv.New64a() h.Write([]byte(v.Response)) k := h.Sum64() buckets[k] = append(buckets[k], v) } } if len(buckets) == 0 { return } // Compress hostnames into ranges res := map[string]uint64{} for hash, resps := range buckets { if len(resps) == 1 { res[resps[0].Host] = hash continue } hosts := []string{} for _, r := range resps { hosts = append(hosts, r.Host) } res[ranges.UnsplitList(hosts)] = hash } // Sort the keys of ranges hosts := []string{} for k := range res { hosts = append(hosts, k) } sort.Strings(hosts) for _, h := range hosts { resp := buckets[res[h]][0] if r.annotate() { buf.Write([]byte(h)) buf.Write([]byte(": ")) } buf.Write([]byte(resp.Response)) buf.Write([]byte("\n")) } }
func cliNamespace(c *minicli.Command, respChan chan<- minicli.Responses) { resp := &minicli.Response{Host: hostname} // Get the active namespace ns := GetNamespace() if name, ok := c.StringArgs["name"]; ok { ns2 := GetOrCreateNamespace(name) if c.Subcommand != nil { // Setting namespace for a single command, revert back afterwards defer RevertNamespace(ns, ns2) SetNamespace(name) // Run the subcommand and forward the responses. // // LOCK: This is a CLI so we already hold cmdLock (can call // runCommands instead of RunCommands). forward(runCommands(c.Subcommand), respChan) return } // Setting namespace for future commands SetNamespace(name) respChan <- minicli.Responses{resp} return } if ns == nil { resp.Response = fmt.Sprintf("Namespaces: %v", ListNamespaces()) respChan <- minicli.Responses{resp} return } hosts := []string{} for h := range ns.Hosts { hosts = append(hosts, h) } // TODO: Make this pretty or divide it up somehow resp.Response = fmt.Sprintf(`Namespace: "%v" Hosts: %v Taps: %v Number of queuedVMs: %v Schedules: `, namespace, ranges.UnsplitList(hosts), ns.Taps, len(ns.queue)) var o bytes.Buffer w := new(tabwriter.Writer) w.Init(&o, 5, 0, 1, ' ', 0) fmt.Fprintln(w, "start\tend\tstate\tlaunched\tfailures\ttotal\thosts") for _, stats := range ns.scheduleStats { var end string if !stats.end.IsZero() { end = fmt.Sprintf("%v", stats.end) } fmt.Fprintf(w, "%v\t%v\t%v\t%v\t%v\t%v\t%v\n", stats.start, end, stats.state, stats.launched, stats.failures, stats.total, stats.hosts) } w.Flush() resp.Response += o.String() respChan <- minicli.Responses{resp} }