func containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerStatus(name) if err != nil { return err } fmt.Printf(gettext.Gettext("Name: %s")+"\n", ct.Name) fmt.Printf(gettext.Gettext("Status: %s")+"\n", ct.Status.Status) if ct.Status.Init != 0 { fmt.Printf(gettext.Gettext("Init: %d")+"\n", ct.Status.Init) fmt.Printf(gettext.Gettext("Processcount: %d")+"\n", ct.Status.Processcount) fmt.Printf(gettext.Gettext("Ips:") + "\n") foundone := false for _, ip := range ct.Status.Ips { vethStr := "" if ip.HostVeth != "" { vethStr = fmt.Sprintf("\t%s", ip.HostVeth) } fmt.Printf(" %s:\t%s\t%s%s\n", ip.Interface, ip.Protocol, ip.Address, vethStr) foundone = true } if !foundone { fmt.Println(gettext.Gettext("(none)")) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(gettext.Gettext("Snapshots:")) } fmt.Printf(" %s\n", snap) first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+gettext.Gettext("Log:")+"\n\n%s\n", string(stuff)) } return nil }
func (c *listCmd) listContainers(d *lxd.Client, cinfos []shared.ContainerInfo, filters []string, columns []column) error { headers := []string{} for _, column := range columns { headers = append(headers, column.Name) } threads := 10 if len(cinfos) < threads { threads = len(cinfos) } cStates := map[string]*shared.ContainerState{} cStatesLock := sync.Mutex{} cStatesQueue := make(chan string, threads) cStatesWg := sync.WaitGroup{} cSnapshots := map[string][]shared.SnapshotInfo{} cSnapshotsLock := sync.Mutex{} cSnapshotsQueue := make(chan string, threads) cSnapshotsWg := sync.WaitGroup{} for i := 0; i < threads; i++ { cStatesWg.Add(1) go func() { d, err := lxd.NewClient(&d.Config, d.Name) if err != nil { cStatesWg.Done() return } for { cName, more := <-cStatesQueue if !more { break } state, err := d.ContainerState(cName) if err != nil { continue } cStatesLock.Lock() cStates[cName] = state cStatesLock.Unlock() } cStatesWg.Done() }() cSnapshotsWg.Add(1) go func() { d, err := lxd.NewClient(&d.Config, d.Name) if err != nil { cSnapshotsWg.Done() return } for { cName, more := <-cSnapshotsQueue if !more { break } snaps, err := d.ListSnapshots(cName) if err != nil { continue } cSnapshotsLock.Lock() cSnapshots[cName] = snaps cSnapshotsLock.Unlock() } cSnapshotsWg.Done() }() } for _, cInfo := range cinfos { for _, column := range columns { if column.NeedsState && cInfo.IsActive() { cStatesLock.Lock() _, ok := cStates[cInfo.Name] cStatesLock.Unlock() if ok { continue } cStatesLock.Lock() cStates[cInfo.Name] = nil cStatesLock.Unlock() cStatesQueue <- cInfo.Name } if column.NeedsSnapshots { cSnapshotsLock.Lock() _, ok := cSnapshots[cInfo.Name] cSnapshotsLock.Unlock() if ok { continue } cSnapshotsLock.Lock() cSnapshots[cInfo.Name] = nil cSnapshotsLock.Unlock() cSnapshotsQueue <- cInfo.Name } } } close(cStatesQueue) close(cSnapshotsQueue) cStatesWg.Wait() cSnapshotsWg.Wait() switch c.format { case listFormatTable: data := [][]string{} for _, cInfo := range cinfos { if !c.shouldShow(filters, &cInfo) { continue } col := []string{} for _, column := range columns { col = append(col, column.Data(cInfo, cStates[cInfo.Name], cSnapshots[cInfo.Name])) } data = append(data, col) } table := tablewriter.NewWriter(os.Stdout) table.SetAutoWrapText(false) table.SetAlignment(tablewriter.ALIGN_LEFT) table.SetRowLine(true) table.SetHeader(headers) sort.Sort(byName(data)) table.AppendBulk(data) table.Render() case listFormatJSON: data := make([]listContainerItem, len(cinfos)) for i := range cinfos { data[i].ContainerInfo = &cinfos[i] data[i].State = cStates[cinfos[i].Name] data[i].Snapshots = cSnapshots[cinfos[i].Name] } enc := json.NewEncoder(os.Stdout) err := enc.Encode(data) if err != nil { return err } default: return fmt.Errorf("invalid format %q", c.format) } return nil }
func containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerStatus(name) if err != nil { return err } const layout = "2006/01/02 15:04 UTC" fmt.Printf(i18n.G("Name: %s")+"\n", ct.Name) if ct.CreationDate != 0 { fmt.Printf(i18n.G("Created: %s")+"\n", time.Unix(ct.CreationDate, 0).UTC().Format(layout)) } fmt.Printf(i18n.G("Status: %s")+"\n", ct.Status.Status) if ct.Ephemeral { fmt.Printf(i18n.G("Type: ephemeral") + "\n") } else { fmt.Printf(i18n.G("Type: persistent") + "\n") } fmt.Printf(i18n.G("Profiles: %s")+"\n", strings.Join(ct.Profiles, ", ")) if ct.Status.Init != 0 { fmt.Printf(i18n.G("Init: %d")+"\n", ct.Status.Init) fmt.Printf(i18n.G("Processcount: %d")+"\n", ct.Status.Processcount) fmt.Printf(i18n.G("Ips:") + "\n") foundone := false for _, ip := range ct.Status.Ips { vethStr := "" if ip.HostVeth != "" { vethStr = fmt.Sprintf("\t%s", ip.HostVeth) } fmt.Printf(" %s:\t%s\t%s%s\n", ip.Interface, ip.Protocol, ip.Address, vethStr) foundone = true } if !foundone { fmt.Println(i18n.G("(none)")) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(i18n.G("Snapshots:")) } fmt.Printf(" %s", snap.Name) if snap.CreationDate != 0 { fmt.Printf(" ("+i18n.G("taken at %s")+")", time.Unix(snap.CreationDate, 0).UTC().Format(layout)) } if snap.Stateful { fmt.Printf(" (" + i18n.G("stateful") + ")") } else { fmt.Printf(" (" + i18n.G("stateless") + ")") } fmt.Printf("\n") first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+i18n.G("Log:")+"\n\n%s\n", string(stuff)) } return nil }
func (c *listCmd) listContainers(d *lxd.Client, cinfos []shared.ContainerInfo, filters []string, columns []column) error { headers := []string{} for _, column := range columns { headers = append(headers, column.Name) } threads := 10 if len(cinfos) < threads { threads = len(cinfos) } cStates := map[string]*shared.ContainerState{} cStatesLock := sync.Mutex{} cStatesQueue := make(chan string, threads) cStatesWg := sync.WaitGroup{} cSnapshots := map[string][]shared.SnapshotInfo{} cSnapshotsLock := sync.Mutex{} cSnapshotsQueue := make(chan string, threads) cSnapshotsWg := sync.WaitGroup{} for i := 0; i < threads; i++ { cStatesWg.Add(1) go func() { for { cName, more := <-cStatesQueue if !more { break } state, err := d.ContainerState(cName) if err != nil { continue } cStatesLock.Lock() cStates[cName] = state cStatesLock.Unlock() } cStatesWg.Done() }() cSnapshotsWg.Add(1) go func() { for { cName, more := <-cSnapshotsQueue if !more { break } snaps, err := d.ListSnapshots(cName) if err != nil { continue } cSnapshotsLock.Lock() cSnapshots[cName] = snaps cSnapshotsLock.Unlock() } cSnapshotsWg.Done() }() } for _, cInfo := range cinfos { if !c.shouldShow(filters, &cInfo) { continue } for _, column := range columns { if column.NeedsState && cInfo.IsActive() { _, ok := cStates[cInfo.Name] if ok { continue } cStatesLock.Lock() cStates[cInfo.Name] = nil cStatesLock.Unlock() cStatesQueue <- cInfo.Name } if column.NeedsSnapshots { _, ok := cSnapshots[cInfo.Name] if ok { continue } cSnapshotsLock.Lock() cSnapshots[cInfo.Name] = nil cSnapshotsLock.Unlock() cSnapshotsQueue <- cInfo.Name } } } close(cStatesQueue) close(cSnapshotsQueue) cStatesWg.Wait() cSnapshotsWg.Wait() data := [][]string{} for _, cInfo := range cinfos { if !c.shouldShow(filters, &cInfo) { continue } col := []string{} for _, column := range columns { col = append(col, column.Data(cInfo, cStates[cInfo.Name], cSnapshots[cInfo.Name])) } data = append(data, col) } table := tablewriter.NewWriter(os.Stdout) table.SetAutoWrapText(false) table.SetAlignment(tablewriter.ALIGN_LEFT) table.SetRowLine(true) table.SetHeader(headers) sort.Sort(byName(data)) table.AppendBulk(data) table.Render() return nil }
func (c *infoCmd) containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerInfo(name) if err != nil { return err } cs, err := d.ContainerState(name) if err != nil { return err } const layout = "2006/01/02 15:04 UTC" fmt.Printf(i18n.G("Name: %s")+"\n", ct.Name) fmt.Printf(i18n.G("Architecture: %s")+"\n", ct.Architecture) if ct.CreationDate.UTC().Unix() != 0 { fmt.Printf(i18n.G("Created: %s")+"\n", ct.CreationDate.UTC().Format(layout)) } fmt.Printf(i18n.G("Status: %s")+"\n", ct.Status) if ct.Ephemeral { fmt.Printf(i18n.G("Type: ephemeral") + "\n") } else { fmt.Printf(i18n.G("Type: persistent") + "\n") } fmt.Printf(i18n.G("Profiles: %s")+"\n", strings.Join(ct.Profiles, ", ")) if cs.Pid != 0 { fmt.Printf(i18n.G("Pid: %d")+"\n", cs.Pid) fmt.Printf(i18n.G("Processes: %d")+"\n", cs.Processes) ipInfo := "" for netName, net := range cs.Network { vethStr := "" if net.HostName != "" { vethStr = fmt.Sprintf("\t%s", net.HostName) } for _, addr := range net.Addresses { ipInfo += fmt.Sprintf(" %s:\t%s\t%s%s\n", netName, addr.Family, addr.Address, vethStr) } } if ipInfo != "" { fmt.Printf(i18n.G("Ips:") + "\n") fmt.Printf(ipInfo) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(i18n.G("Snapshots:")) } fmt.Printf(" %s", snap.Name) if snap.CreationDate.UTC().Unix() != 0 { fmt.Printf(" ("+i18n.G("taken at %s")+")", snap.CreationDate.UTC().Format(layout)) } if snap.Stateful { fmt.Printf(" (" + i18n.G("stateful") + ")") } else { fmt.Printf(" (" + i18n.G("stateless") + ")") } fmt.Printf("\n") first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+i18n.G("Log:")+"\n\n%s\n", string(stuff)) } return nil }
func (c *infoCmd) containerInfo(d *lxd.Client, name string, showLog bool) error { ct, err := d.ContainerInfo(name) if err != nil { return err } cs, err := d.ContainerState(name) if err != nil { return err } const layout = "2006/01/02 15:04 UTC" fmt.Printf(i18n.G("Name: %s")+"\n", ct.Name) if d.Remote != nil && d.Remote.Addr != "" { fmt.Printf(i18n.G("Remote: %s")+"\n", d.Remote.Addr) } fmt.Printf(i18n.G("Architecture: %s")+"\n", ct.Architecture) if ct.CreationDate.UTC().Unix() != 0 { fmt.Printf(i18n.G("Created: %s")+"\n", ct.CreationDate.UTC().Format(layout)) } fmt.Printf(i18n.G("Status: %s")+"\n", ct.Status) if ct.Ephemeral { fmt.Printf(i18n.G("Type: ephemeral") + "\n") } else { fmt.Printf(i18n.G("Type: persistent") + "\n") } fmt.Printf(i18n.G("Profiles: %s")+"\n", strings.Join(ct.Profiles, ", ")) if cs.Pid != 0 { fmt.Printf(i18n.G("Pid: %d")+"\n", cs.Pid) // IP addresses ipInfo := "" if cs.Network != nil { for netName, net := range cs.Network { vethStr := "" if net.HostName != "" { vethStr = fmt.Sprintf("\t%s", net.HostName) } for _, addr := range net.Addresses { ipInfo += fmt.Sprintf(" %s:\t%s\t%s%s\n", netName, addr.Family, addr.Address, vethStr) } } } if ipInfo != "" { fmt.Println(i18n.G("Ips:")) fmt.Printf(ipInfo) } fmt.Println(i18n.G("Resources:")) // Processes fmt.Printf(" "+i18n.G("Processes: %d")+"\n", cs.Processes) // Disk usage diskInfo := "" if cs.Disk != nil { for entry, disk := range cs.Disk { if disk.Usage != 0 { diskInfo += fmt.Sprintf(" %s: %s\n", entry, shared.GetByteSizeString(disk.Usage)) } } } if diskInfo != "" { fmt.Println(i18n.G(" Disk usage:")) fmt.Printf(diskInfo) } // CPU usage cpuInfo := "" if cs.CPU.Usage != 0 { cpuInfo += fmt.Sprintf(" %s: %v\n", i18n.G("CPU usage (in seconds)"), cs.CPU.Usage/1000000000) } if cpuInfo != "" { fmt.Println(i18n.G(" CPU usage:")) fmt.Printf(cpuInfo) } // Memory usage memoryInfo := "" if cs.Memory.Usage != 0 { memoryInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Memory (current)"), shared.GetByteSizeString(cs.Memory.Usage)) } if cs.Memory.UsagePeak != 0 { memoryInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Memory (peak)"), shared.GetByteSizeString(cs.Memory.UsagePeak)) } if cs.Memory.SwapUsage != 0 { memoryInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Swap (current)"), shared.GetByteSizeString(cs.Memory.SwapUsage)) } if cs.Memory.SwapUsagePeak != 0 { memoryInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Swap (peak)"), shared.GetByteSizeString(cs.Memory.SwapUsagePeak)) } if memoryInfo != "" { fmt.Println(i18n.G(" Memory usage:")) fmt.Printf(memoryInfo) } // Network usage networkInfo := "" if cs.Network != nil { for netName, net := range cs.Network { networkInfo += fmt.Sprintf(" %s:\n", netName) networkInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Bytes received"), shared.GetByteSizeString(net.Counters.BytesReceived)) networkInfo += fmt.Sprintf(" %s: %s\n", i18n.G("Bytes sent"), shared.GetByteSizeString(net.Counters.BytesSent)) networkInfo += fmt.Sprintf(" %s: %d\n", i18n.G("Packets received"), net.Counters.PacketsReceived) networkInfo += fmt.Sprintf(" %s: %d\n", i18n.G("Packets sent"), net.Counters.PacketsSent) } } if networkInfo != "" { fmt.Println(i18n.G(" Network usage:")) fmt.Printf(networkInfo) } } // List snapshots first_snapshot := true snaps, err := d.ListSnapshots(name) if err != nil { return nil } for _, snap := range snaps { if first_snapshot { fmt.Println(i18n.G("Snapshots:")) } fields := strings.Split(snap.Name, shared.SnapshotDelimiter) fmt.Printf(" %s", fields[len(fields)-1]) if snap.CreationDate.UTC().Unix() != 0 { fmt.Printf(" ("+i18n.G("taken at %s")+")", snap.CreationDate.UTC().Format(layout)) } if snap.Stateful { fmt.Printf(" (" + i18n.G("stateful") + ")") } else { fmt.Printf(" (" + i18n.G("stateless") + ")") } fmt.Printf("\n") first_snapshot = false } if showLog { log, err := d.GetLog(name, "lxc.log") if err != nil { return err } stuff, err := ioutil.ReadAll(log) if err != nil { return err } fmt.Printf("\n"+i18n.G("Log:")+"\n\n%s\n", string(stuff)) } return nil }