Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to output ls/ps in json format #889

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cmd/edenNetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,21 @@ func newNetworkCmd() *cobra.Command {
}

func newNetworkLsCmd() *cobra.Command {
var outputFormat types.OutputFormat
//networkLsCmd is a command to list deployed network instances
var networkLsCmd = &cobra.Command{
Use: "ls",
Short: "List networks",
Run: func(cmd *cobra.Command, args []string) {
if err := openevec.NetworkLs(); err != nil {
if err := openevec.NetworkLs(outputFormat); err != nil {
log.Fatal(err)
}
},
}
networkLsCmd.Flags().Var(
enumflag.New(&outputFormat, "format", outputFormatIds, enumflag.EnumCaseInsensitive),
"format",
"Format to print logs, supports: lines, json")
return networkLsCmd
}

Expand Down
7 changes: 6 additions & 1 deletion cmd/edenPod.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,20 @@ You can set access VLAN ID (VID) for a particular network in the format '<networ
}

func newPodPsCmd(cfg *openevec.EdenSetupArgs) *cobra.Command {
var outputFormat types.OutputFormat
var podPsCmd = &cobra.Command{
Use: "ps",
Short: "List pods",
Run: func(cmd *cobra.Command, args []string) {
if err := openevec.PodPs(cfg); err != nil {
if err := openevec.PodPs(cfg, outputFormat); err != nil {
log.Fatalf("EVE pod deploy failed: %s", err)
}
},
}
podPsCmd.Flags().Var(
enumflag.New(&outputFormat, "format", outputFormatIds, enumflag.EnumCaseInsensitive),
"format",
"Format to print logs, supports: lines, json")

return podPsCmd
}
Expand Down
9 changes: 8 additions & 1 deletion cmd/edenVolume.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package cmd

import (
"github.com/dustin/go-humanize"
"github.com/lf-edge/eden/pkg/controller/types"
"github.com/lf-edge/eden/pkg/openevec"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/thediveo/enumflag"
)

func newVolumeCmd() *cobra.Command {
Expand All @@ -31,16 +33,21 @@ func newVolumeCmd() *cobra.Command {
}

func newVolumeLsCmd() *cobra.Command {
var outputFormat types.OutputFormat
//volumeLsCmd is a command to list deployed volumes
var volumeLsCmd = &cobra.Command{
Use: "ls",
Short: "List volumes",
Run: func(cmd *cobra.Command, args []string) {
if err := openevec.VolumeLs(); err != nil {
if err := openevec.VolumeLs(outputFormat); err != nil {
log.Fatal(err)
}
},
}
volumeLsCmd.Flags().Var(
enumflag.New(&outputFormat, "format", outputFormatIds, enumflag.EnumCaseInsensitive),
"format",
"Format to print logs, supports: lines, json")
return volumeLsCmd
}

Expand Down
81 changes: 58 additions & 23 deletions pkg/eve/applications.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eve

import (
"encoding/json"
"fmt"
"os"
"sort"
Expand All @@ -11,13 +12,14 @@ import (

"github.com/dustin/go-humanize"
"github.com/lf-edge/eden/pkg/controller"
"github.com/lf-edge/eden/pkg/controller/types"
"github.com/lf-edge/eden/pkg/device"
"github.com/lf-edge/eve/api/go/config"
"github.com/lf-edge/eve/api/go/info"
"github.com/lf-edge/eve/api/go/metrics"
)

//AppInstState stores state of app
// AppInstState stores state of app
type AppInstState struct {
Name string
UUID string
Expand All @@ -28,11 +30,16 @@ type AppInstState struct {
ExternalIP string
InternalPort string
ExternalPort string
Memory string
macs []string
volumes map[string]uint32
deleted bool
infoTime time.Time
MemoryUsed uint32
MemoryAvail uint32
CPUUsage int
Macs []string
Volumes map[string]uint32

prevCPUNS uint64
prevCPUNSTime time.Time
deleted bool
infoTime time.Time
}

func appStateHeader() string {
Expand Down Expand Up @@ -66,9 +73,12 @@ func (appStateObj *AppInstState) toString() string {
if appStateObj.ExternalPort == "" {
external = "-"
}
memory := fmt.Sprintf("%s/%s",
humanize.Bytes((uint64)(appStateObj.MemoryUsed*humanize.MByte)),
humanize.Bytes((uint64)(appStateObj.MemoryAvail*humanize.MByte)))
return fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
appStateObj.Name, appStateObj.Image, appStateObj.UUID,
internal, external, appStateObj.Memory,
internal, external, memory,
appStateObj.AdamState, appStateObj.EVEState)
}

Expand Down Expand Up @@ -131,7 +141,7 @@ func (ctx *State) initApplications(ctrl controller.Cloud, dev *device.Ctx) error
ExternalIP: "-",
InternalPort: intPort,
ExternalPort: extPort,
volumes: volumes,
Volumes: volumes,
UUID: app.Uuidandversion.Uuid,
}
ctx.applications[app.Uuidandversion.Uuid] = appStateObj
Expand All @@ -144,9 +154,14 @@ func (ctx *State) processApplicationsByMetric(msg *metrics.ZMetricMsg) {
for _, appMetric := range appMetrics {
for _, el := range ctx.applications {
if appMetric.AppID == el.UUID {
el.Memory = fmt.Sprintf("%s/%s",
humanize.Bytes((uint64)(appMetric.Memory.GetUsedMem()*humanize.MByte)),
humanize.Bytes((uint64)(appMetric.Memory.GetAvailMem()*humanize.MByte)))
el.MemoryAvail = appMetric.Memory.GetAvailMem()
el.MemoryUsed = appMetric.Memory.GetUsedMem()
// if not restarted
if el.prevCPUNS < appMetric.Cpu.TotalNs {
el.CPUUsage = int(float32(appMetric.Cpu.TotalNs-el.prevCPUNS) / float32(msg.GetAtTimeStamp().AsTime().Sub(el.prevCPUNSTime).Nanoseconds()) * 100.0)
}
el.prevCPUNS = appMetric.Cpu.TotalNs
el.prevCPUNSTime = msg.GetAtTimeStamp().AsTime()
break
}
}
Expand All @@ -158,19 +173,19 @@ func (ctx *State) processApplicationsByInfo(im *info.ZInfoMsg) {
switch im.GetZtype() {
case info.ZInfoTypes_ZiVolume:
for _, app := range ctx.applications {
if len(app.volumes) == 0 {
if len(app.Volumes) == 0 {
continue
}
var percent uint32
for vol := range app.volumes {
percent += app.volumes[vol] //we sum all percents of all volumes and will divide them by count
for vol := range app.Volumes {
percent += app.Volumes[vol] //we sum all percents of all volumes and will divide them by count
if im.GetVinfo().Uuid == vol {
app.volumes[vol] = im.GetVinfo().ProgressPercentage
app.Volumes[vol] = im.GetVinfo().ProgressPercentage
break
}
}
if strings.HasPrefix(app.EVEState, info.ZSwState_DOWNLOAD_STARTED.String()) {
app.EVEState = fmt.Sprintf("%s (%d%%)", info.ZSwState_DOWNLOAD_STARTED.String(), int(percent)/len(app.volumes))
app.EVEState = fmt.Sprintf("%s (%d%%)", info.ZSwState_DOWNLOAD_STARTED.String(), int(percent)/len(app.Volumes))
}
}
case info.ZInfoTypes_ZiApp:
Expand All @@ -192,22 +207,22 @@ func (ctx *State) processApplicationsByInfo(im *info.ZInfoMsg) {
if len(im.GetAinfo().Network) != 0 && len(im.GetAinfo().Network[0].IPAddrs) != 0 {
if len(im.GetAinfo().Network) > 1 {
appStateObj.InternalIP = []string{}
appStateObj.macs = []string{}
appStateObj.Macs = []string{}
for _, el := range im.GetAinfo().Network {
if len(el.IPAddrs) != 0 {
appStateObj.InternalIP = append(appStateObj.InternalIP, el.IPAddrs[0])
appStateObj.macs = append(appStateObj.macs, el.MacAddr)
appStateObj.Macs = append(appStateObj.Macs, el.MacAddr)
}
}
} else {
if len(im.GetAinfo().Network[0].IPAddrs) != 0 {
appStateObj.InternalIP = []string{im.GetAinfo().Network[0].IPAddrs[0]}
appStateObj.macs = []string{im.GetAinfo().Network[0].MacAddr}
appStateObj.Macs = []string{im.GetAinfo().Network[0].MacAddr}
}
}
} else {
appStateObj.InternalIP = []string{"-"}
appStateObj.macs = []string{}
appStateObj.Macs = []string{}
}
//check appStateObj not defined in adam
if appStateObj.AdamState != inControllerConfig {
Expand All @@ -222,7 +237,7 @@ func (ctx *State) processApplicationsByInfo(im *info.ZInfoMsg) {
case info.ZInfoTypes_ZiNetworkInstance: //try to find ips from NetworkInstances
for _, el := range im.GetNiinfo().IpAssignments {
for _, appStateObj := range ctx.applications {
for ind, mac := range appStateObj.macs {
for ind, mac := range appStateObj.Macs {
if mac == el.MacAddress {
appStateObj.InternalIP[ind] = el.IpAddress[0]
}
Expand Down Expand Up @@ -283,8 +298,7 @@ func (ctx *State) processApplicationsByInfo(im *info.ZInfoMsg) {
}
}

//PodsList prints applications
func (ctx *State) PodsList() error {
func (ctx *State) printPodListLines() error {
w := new(tabwriter.Writer)
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
if _, err := fmt.Fprintln(w, appStateHeader()); err != nil {
Expand All @@ -302,3 +316,24 @@ func (ctx *State) PodsList() error {
}
return w.Flush()
}

func (ctx *State) printPodListJSON() error {
result, err := json.MarshalIndent(ctx.Applications(), "", " ")
if err != nil {
return err
}
//nolint:forbidigo
fmt.Println(string(result))
return nil
}

// PodsList prints applications
func (ctx *State) PodsList(outputFormat types.OutputFormat) error {
switch outputFormat {
case types.OutputFormatLines:
return ctx.printPodListLines()
case types.OutputFormatJSON:
return ctx.printPodListJSON()
}
return fmt.Errorf("unimplemented output format")
}
32 changes: 27 additions & 5 deletions pkg/eve/networks.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package eve

import (
"encoding/json"
"fmt"
"os"
"sort"
"text/tabwriter"

"github.com/lf-edge/eden/pkg/controller"
"github.com/lf-edge/eden/pkg/controller/types"
"github.com/lf-edge/eden/pkg/device"
"github.com/lf-edge/eve/api/go/config"
"github.com/lf-edge/eve/api/go/info"
Expand All @@ -17,7 +19,7 @@ import (
type NetInstState struct {
Name string
UUID string
NetworkType config.ZNetworkInstType
NetworkType string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would we want to switch to string?

Copy link
Collaborator Author

@giggsoff giggsoff Aug 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experiments I received value of variable here (some number), not a meaningful text (ZnetInstLocal from my sample). It is quite tricky to format it on-fly in marshaller.

CIDR string
Stats string
AdamState string
Expand Down Expand Up @@ -51,7 +53,7 @@ func (ctx *State) initNetworks(ctrl controller.Cloud, dev *device.Ctx) error {
AdamState: inControllerConfig,
EveState: "UNKNOWN",
CIDR: ni.Ip.Subnet,
NetworkType: ni.InstType,
NetworkType: ni.InstType.String(),
}
ctx.networks[ni.Uuidandversion.Uuid] = netInstStateObj
}
Expand All @@ -69,7 +71,7 @@ func (ctx *State) processNetworksByInfo(im *info.ZInfoMsg) {
Stats: "-",
AdamState: notInControllerConfig,
EveState: "UNKNOWN",
NetworkType: (config.ZNetworkInstType)(int32(im.GetNiinfo().InstType)),
NetworkType: (config.ZNetworkInstType)(int32(im.GetNiinfo().InstType)).String(),
}
ctx.networks[im.GetNiinfo().GetNetworkID()] = netInstStateObj
}
Expand Down Expand Up @@ -120,8 +122,7 @@ func (ctx *State) processNetworksByMetric(msg *metrics.ZMetricMsg) {
}
}

// NetList prints networks
func (ctx *State) NetList() error {
func (ctx *State) printNetListLines() error {
w := new(tabwriter.Writer)
w.Init(os.Stdout, 0, 8, 1, '\t', 0)
if _, err := fmt.Fprintln(w, netInstStateHeader()); err != nil {
Expand All @@ -139,3 +140,24 @@ func (ctx *State) NetList() error {
}
return w.Flush()
}

func (ctx *State) printNetListJSON() error {
result, err := json.MarshalIndent(ctx.Networks(), "", " ")
if err != nil {
return err
}
//nolint:forbidigo
fmt.Println(string(result))
return nil
}

// NetList prints networks
func (ctx *State) NetList(outputFormat types.OutputFormat) error {
switch outputFormat {
case types.OutputFormatLines:
return ctx.printNetListLines()
case types.OutputFormatJSON:
return ctx.printNetListJSON()
}
return fmt.Errorf("unimplemented output format")
}
Loading
Loading