From patchwork Thu May 16 15:41:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakob Meng X-Patchwork-Id: 1936052 X-Patchwork-Delegate: i.maximets@samsung.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cA6PZ1sn; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VgDpt3ttNz1ymw for ; Fri, 17 May 2024 01:41:42 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 972224169E; Thu, 16 May 2024 15:41:38 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id kY_ekNtzCdaE; Thu, 16 May 2024 15:41:37 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 25D17416C3 Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cA6PZ1sn Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 25D17416C3; Thu, 16 May 2024 15:41:35 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 25454C0DCF; Thu, 16 May 2024 15:41:35 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id E1C0CC0077 for ; Thu, 16 May 2024 15:41:30 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id C295D60E7C for ; Thu, 16 May 2024 15:41:30 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Ez5X4yEip3J9 for ; Thu, 16 May 2024 15:41:30 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=jmeng@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org CC02760847 Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org CC02760847 Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cA6PZ1sn Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id CC02760847 for ; Thu, 16 May 2024 15:41:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715874088; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4YusQp1ux8ZEvGXcSoQH1pxpJqOZMy2ZiwZtWAigL14=; b=cA6PZ1snCg2cqj9AZoN+4nYCQGP1tzzq1SXdlLzfzwSAkZcOg+BDifAC50NSijaXPEMhlR 5jlTZFWq8qZZyOlofk8lQV/0DgwYG66hJIQYDQWLYs23E+Yr8MhjQnUglg6ivEDdufyQgB LwtVKCAvzUHh20JGt4asTYjM54Q0qWI= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-260--W7Yn5SQOfuK_pv5Z9E-FQ-1; Thu, 16 May 2024 11:41:27 -0400 X-MC-Unique: -W7Yn5SQOfuK_pv5Z9E-FQ-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-34dc7b83209so4517032f8f.2 for ; Thu, 16 May 2024 08:41:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715874085; x=1716478885; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4YusQp1ux8ZEvGXcSoQH1pxpJqOZMy2ZiwZtWAigL14=; b=nDOfCURVJHfsIQZy+4YRq3gf6eJKLHYNH4NgzJ0CH6qoixpVJGlOzbS6ykLnrB96FV n+mua3omu7gvuSxMHhsUHqKMQ+G7A/GrWTfagG0BFsZu5NySdn7twDlfXh1Rv+EjcmQ8 gLRArlbT+NUtGCaHqxg9hgbc1EB6oAoWRwE01jYJX0c36TmgHMUGfQfTvmazKfQ7QrPd +pUyovqqHLzjfOuyj8S1pVyqdOD2drwzj7jGuMqdJyWDXMqeu4XOeUiJK12ZM/q7cimI fYEOUbCJoeLonZpuYSkoqgc1ymku7+MMrDE8XTPIiYkWnJ0Z4q2UgbLblDi2KHzbE3Aj SAzA== X-Gm-Message-State: AOJu0YzZ6KfdFOWIIPggK5uOojV6PdOzEo03MEZTN+F5vFjfiG/OXnxo STmaFWrmh0aqTMf8RQCFdOwnJLS6A1Kzw5v5+3Sj43EEK7obyZuYQY6P2xEMiPbRrbyxX/MrkFy Ki3GZ12ILFJ+gv9GSIHOTuZC/8SvI58pdI1DAYIbwKMsRjburqdvYzlCBWRuiJbjcLWBduGBNLQ Pp4wRqYNlGw6zOBD65o+iZYyJvjOPM X-Received: by 2002:adf:e68f:0:b0:351:d3e1:97e6 with SMTP id ffacd0b85a97d-351d3e1982dmr2713036f8f.26.1715874085423; Thu, 16 May 2024 08:41:25 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF9pSswS7ZfXwDqQDGCRUYGXJ95khnSVKupDhMmL3LmgQu51DK1FzCMpL3QVbEusUmRRgW59Q== X-Received: by 2002:adf:e68f:0:b0:351:d3e1:97e6 with SMTP id ffacd0b85a97d-351d3e1982dmr2713014f8f.26.1715874084937; Thu, 16 May 2024 08:41:24 -0700 (PDT) Received: from positronik4lide.redhat.com ([87.122.57.114]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3502bbbbf9esm19177266f8f.91.2024.05.16.08.41.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 May 2024 08:41:24 -0700 (PDT) From: jmeng@redhat.com To: dev@openvswitch.org, i.maximets@ovn.org Date: Thu, 16 May 2024 17:41:14 +0200 Message-Id: <20240516154117.2306789-4-jmeng@redhat.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240516154117.2306789-1-jmeng@redhat.com> References: <20240516154117.2306789-1-jmeng@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v12 3/6] appctl: Add option '--pretty' for pretty-printing JSON output. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Jakob Meng With the '--pretty' option, ovs-appctl will now print JSON output in a more readable fashion, i.e. with additional line breaks, spaces and sorted dictionary keys. Signed-off-by: Jakob Meng --- Documentation/ref/ovs-appctl.8.rst | 7 ++++++ NEWS | 1 + tests/ovs-vswitchd.at | 5 +++++ utilities/ovs-appctl.c | 34 ++++++++++++++++++++++++------ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Documentation/ref/ovs-appctl.8.rst b/Documentation/ref/ovs-appctl.8.rst index 9619c1226..db6c52b42 100644 --- a/Documentation/ref/ovs-appctl.8.rst +++ b/Documentation/ref/ovs-appctl.8.rst @@ -79,6 +79,13 @@ In normal use only a single option is accepted: ``{"reply-format":"plain","reply":"$PLAIN_TEXT_HERE"}`` +* ``--pretty`` + + By default, JSON output is printed as compactly as possible. This option + causes JSON in output to be printed in a more readable fashion. For example, + members of objects and elements of arrays are printed one per line, with + indentation. Requires ``--format=json``. + Common Commands =============== diff --git a/NEWS b/NEWS index 7076939c5..0d41061d3 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Post-v3.3.0 - ovs-appctl: * Added new option [-f|--format] to choose the output format, e.g. 'json' or 'text' (by default). + * Added new option [--pretty] to print JSON output in a readable fashion. - Python: * Added support for different output formats like 'json' to appctl.py and Python's unixctl classes. diff --git a/tests/ovs-vswitchd.at b/tests/ovs-vswitchd.at index 1ae7fcc32..2db8138f1 100644 --- a/tests/ovs-vswitchd.at +++ b/tests/ovs-vswitchd.at @@ -275,4 +275,9 @@ ovs_version=$(ovs-appctl version) AT_CHECK_UNQUOTED([ovs-appctl --format json version], [0], [dnl {"reply":"$ovs_version","reply-format":"plain"}]) +AT_CHECK_UNQUOTED([ovs-appctl --format json --pretty version], [0], [dnl +{ + "reply": "$ovs_version", + "reply-format": "plain"}]) + AT_CLEANUP diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c index 0e99259e8..3b76740ea 100644 --- a/utilities/ovs-appctl.c +++ b/utilities/ovs-appctl.c @@ -40,13 +40,15 @@ static void usage(void); /* Parsed command line args. */ struct cmdl_args { enum unixctl_output_fmt format; + unsigned int format_flags; char *target; }; static struct cmdl_args *cmdl_args_create(void); static struct cmdl_args *parse_command_line(int argc, char *argv[]); static struct jsonrpc *connect_to_target(const char *target); -static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt); +static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, + unsigned int fmt_flags); int main(int argc, char *argv[]) @@ -84,7 +86,7 @@ main(int argc, char *argv[]) if (cmd_error) { jsonrpc_close(client); - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); fputs(msg, stderr); free(msg); ovs_error(0, "%s: server returned an error", args->target); @@ -108,13 +110,13 @@ main(int argc, char *argv[]) if (cmd_error) { jsonrpc_close(client); - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); fputs(msg, stderr); free(msg); ovs_error(0, "%s: server returned an error", args->target); exit(2); } else if (cmd_result) { - msg = reply_to_string(cmd_result, args->format); + msg = reply_to_string(cmd_result, args->format, args->format_flags); fputs(msg, stdout); free(msg); } else { @@ -151,6 +153,8 @@ Other options:\n\ --timeout=SECS wait at most SECS seconds for a response\n\ -f, --format=FMT Output format. One of: 'json', or 'text'\n\ (default: text)\n\ + --pretty Format the output in a more readable fashion.\n\ + Requires: --format=json.\n\ -h, --help Print this helpful information\n\ -V, --version Display ovs-appctl version information\n", program_name, program_name); @@ -163,6 +167,7 @@ cmdl_args_create(void) struct cmdl_args *args = xmalloc(sizeof *args); args->format = UNIXCTL_OUTPUT_FMT_TEXT; + args->format_flags = 0; args->target = NULL; return args; @@ -173,7 +178,8 @@ parse_command_line(int argc, char *argv[]) { enum { OPT_START = UCHAR_MAX + 1, - VLOG_OPTION_ENUMS + OPT_PRETTY, + VLOG_OPTION_ENUMS, }; static const struct option long_options[] = { {"target", required_argument, NULL, 't'}, @@ -181,6 +187,7 @@ parse_command_line(int argc, char *argv[]) {"format", required_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h'}, {"option", no_argument, NULL, 'o'}, + {"pretty", no_argument, NULL, OPT_PRETTY}, {"version", no_argument, NULL, 'V'}, {"timeout", required_argument, NULL, 'T'}, VLOG_LONG_OPTIONS, @@ -190,6 +197,7 @@ parse_command_line(int argc, char *argv[]) char *short_options = xasprintf("+%s", short_options_); struct cmdl_args *args = cmdl_args_create(); unsigned int timeout = 0; + bool pretty = false; int e_options; e_options = 0; @@ -232,6 +240,10 @@ parse_command_line(int argc, char *argv[]) ovs_cmdl_print_options(long_options); exit(EXIT_SUCCESS); + case OPT_PRETTY: + pretty = true; + break; + case 'T': if (!str_to_uint(optarg, 10, &timeout) || !timeout) { ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg); @@ -261,6 +273,13 @@ parse_command_line(int argc, char *argv[]) "(use --help for help)"); } + if (pretty) { + if (args->format != UNIXCTL_OUTPUT_FMT_JSON) { + ovs_fatal(0, "--pretty is supported with --format json only"); + } + args->format_flags |= JSSF_PRETTY; + } + if (!args->target) { args->target = "ovs-vswitchd"; } @@ -309,7 +328,8 @@ connect_to_target(const char *target) /* The caller is responsible for freeing the returned string, with free(), when * it is no longer needed. */ static char * -reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) +reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, + unsigned int fmt_flags) { ovs_assert(reply); @@ -328,5 +348,5 @@ reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) json_type_to_string(reply->type)); } - return json_to_string(reply, JSSF_SORT); + return json_to_string(reply, JSSF_SORT | fmt_flags); }