Skip to content

Commit

Permalink
cmd/list: Add type assertions and error reporter
Browse files Browse the repository at this point in the history
Every time Podman changes their JSON API Toolbox breaks horribly. That
is caused by the complete lack of type guards. With this the verbosity
of the code goes up a bit but it should be much more resistant to API
changes.

If a field is of a not-expected type, the field is set to "<error>" and
an error message is printed after the rest of the table is printed into
the console.
  • Loading branch information
HarryMichal committed Jul 14, 2020
1 parent bf815d3 commit afd6286
Showing 1 changed file with 74 additions and 13 deletions.
87 changes: 74 additions & 13 deletions src/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ func listImages() ([]map[string]interface{}, error) {

func listOutput(images, containers []map[string]interface{}) {
if len(images) != 0 {
var err error = nil
writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(writer, "%s\t%s\t%s\n", "IMAGE ID", "IMAGE NAME", "CREATED")

Expand All @@ -202,21 +203,47 @@ func listOutput(images, containers []map[string]interface{}) {
createdKey = "created"
}

var id, name, created string
for _, image := range images {
id := utils.ShortID(image[idKey].(string))
name := image[nameKey].([]interface{})[0].(string)
created := image[createdKey].(string)
switch value := image[idKey].(type) {
case string:
id = utils.ShortID(value)
default:
id = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, image[idKey])
}

switch value := image[nameKey].(type) {
case []interface{}:
name = value[0].(string)
default:
name = "<error>"
err = fmt.Errorf("expected type of field %s is []interface{}, found %T", idKey, image[nameKey])
}

switch value := image[createdKey].(type) {
case string:
created = value
default:
created = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, image[createdKey])
}

fmt.Fprintf(writer, "%s\t%s\t%s\n", id, name, created)
}

writer.Flush()
if err != nil {
logrus.Errorf("There was an error while listing toolbox images: %v", err)
}
}

if len(images) != 0 && len(containers) != 0 {
fmt.Println()
}

if len(containers) != 0 {
var err error = nil
writer := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(writer,
"%s\t%s\t%s\t%s\t%s\n",
Expand All @@ -226,7 +253,7 @@ func listOutput(images, containers []map[string]interface{}) {
"STATUS",
"IMAGE NAME")

var idKey, createdKey, statusKey string
var idKey, namesKey, createdKey, statusKey, imageKey string
if podman.CheckVersion("2.0.0") {
idKey = "Id"
createdKey = "CreatedAt"
Expand All @@ -236,25 +263,59 @@ func listOutput(images, containers []map[string]interface{}) {
createdKey = "Created"
statusKey = "Status"
}
namesKey = "Names"
imageKey = "Image"

var id, name, created, status, imageName string
for _, container := range containers {
id := utils.ShortID(container[idKey].(string))
switch value := container[idKey].(type) {
case string:
id = utils.ShortID(value)
default:
id = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, container[createdKey])
}

var nameString string
switch name := container["Names"].(type) {
switch value := container[namesKey].(type) {
case string:
nameString = name
name = value
case []interface{}:
nameString = name[0].(string)
name = value[0].(string)
default:
name = "<error>"
err = fmt.Errorf("expected type of field %s is string or []interface{}, found %T", idKey, container[namesKey])
}

switch value := container[createdKey].(type) {
case string:
created = value
default:
created = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, container[createdKey])
}

created := container[createdKey].(string)
status := container[statusKey].(string)
imageName := container["Image"].(string)
switch value := container[statusKey].(type) {
case string:
status = value
default:
status = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, container[statusKey])
}

fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s\n", id, nameString, created, status, imageName)
switch value := container[imageKey].(type) {
case string:
imageName = value
default:
imageName = "<error>"
err = fmt.Errorf("expected type of field %s is string, found %T", idKey, container[imageKey])
}

fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s\n", id, name, created, status, imageName)
}

writer.Flush()
if err != nil {
logrus.Errorf("There was an error while listing toolbox containers: %v", err)
}
}
}

0 comments on commit afd6286

Please sign in to comment.