From f270c7f092ed823e3498901e9ae3222182422513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20M=C3=ADchal?= Date: Tue, 14 Jul 2020 20:17:40 +0200 Subject: [PATCH] cmd/list: Add type assertions and error reporter 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 "" and an error message is printed after the rest of the table is printed into the console. --- src/cmd/list.go | 87 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/src/cmd/list.go b/src/cmd/list.go index 7188701b7..2904022eb 100644 --- a/src/cmd/list.go +++ b/src/cmd/list.go @@ -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") @@ -202,14 +203,39 @@ 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 = "" + 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 = "" + 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 = "" + 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: %w", err) + } } if len(images) != 0 && len(containers) != 0 { @@ -217,6 +243,7 @@ func listOutput(images, containers []map[string]interface{}) { } 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", @@ -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" @@ -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 = "" + 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 = "" + 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 = "" + 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 = "" + 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 = "" + 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: %w", err) + } } }