From patchwork Thu Apr 11 14:47:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakob Meng X-Patchwork-Id: 1922612 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=E+PoVKHG; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (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 4VFjGq5DDHz1yYB for ; Fri, 12 Apr 2024 00:47:47 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id F23CC41ACC; Thu, 11 Apr 2024 14:47:43 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id mY3PoKVtvbJU; Thu, 11 Apr 2024 14:47:40 +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 smtp2.osuosl.org E548641A6E Authentication-Results: smtp2.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=E+PoVKHG Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id E548641A6E; Thu, 11 Apr 2024 14:47:39 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id AFB17C0DD2; Thu, 11 Apr 2024 14:47:39 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 09579C0077 for ; Thu, 11 Apr 2024 14:47:38 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id E7725612C4 for ; Thu, 11 Apr 2024 14:47:37 +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 M31DOX_JYNeD for ; Thu, 11 Apr 2024 14:47:37 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=jmeng@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org EBC10612C2 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 EBC10612C2 Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=E+PoVKHG Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id EBC10612C2 for ; Thu, 11 Apr 2024 14:47:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712846855; 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=GqOpqFhwTbw+r61xgEEyjyFODlKUU/aWzxF2GsJiV1s=; b=E+PoVKHGWcaO8SInAjVD7gvM06YJuByWm+uN7wZPFlajuAq9Tr2ymKPijOKptdqYC4A/Fo Oc4gUrgC5uZJnPRWihxZobb4vLPfnpbgaReGgZ8wzmeLz7EUS960lJlb+WnNoEqSXtNZoM GLF9ZQZF6uMnEImimuy5b7yLFdOjjLI= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-283-_twzjfhgPfuGdDvX5WA59w-1; Thu, 11 Apr 2024 10:47:34 -0400 X-MC-Unique: _twzjfhgPfuGdDvX5WA59w-1 Received: by mail-ej1-f70.google.com with SMTP id a640c23a62f3a-a51ad5289acso388777166b.1 for ; Thu, 11 Apr 2024 07:47:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712846853; x=1713451653; 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=GqOpqFhwTbw+r61xgEEyjyFODlKUU/aWzxF2GsJiV1s=; b=G42haX+p/ITJ3N4s6E2OoYc1SXCXesp1QG3Rlhea4lxx5CMt0XCQUKu8jy6cKh8iSQ 3eH6v+klX/PoVfziTmlOAox9s0dlehfaBaA1Q64ClSUHACH+nD9m6NaAUups/sVBVqd5 mnXEubPi2kF5op//M44l+oycFwQqlD8FjpbeSNrX9PHU1T6lGUhiDsXjjGfyN0QY6YvX wvScy9kybTBD1bLNKcs1IgNYp9i72ahEcYZyNZtAgKkeqMWQtYOK8az/KZBaKsZxZLjz 4qlHije+vUe9vRPjCiPyUb9/slshY7pSpsdMW2zYP2LLOSeuMGDReFLzdGFY3oSfV5UV LJBA== X-Gm-Message-State: AOJu0Yw41CSTerSO0bzju0m3+PXqK9W1PnZkP8249LN+KmKs3eU9+pXv MeeOb9FEoD4n04P2zSeqGMwM+3y4KITuuZlm33qm074ncpthNeA69rcx03XXkIiutQic8evHk4g fLw9eFFhZqTlktVo1euVNgOBYWzrCGexdqbf05TWDUsiKAGu3a+Z1eHhY7FkvDTwVu2xp6jTBfO 5ztwl5KBd9FdlpMsrxfkj0vtwyZuE3 X-Received: by 2002:a17:906:50b:b0:a52:2a91:eebd with SMTP id j11-20020a170906050b00b00a522a91eebdmr728224eja.75.1712846852952; Thu, 11 Apr 2024 07:47:32 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHg2BBWGCva3bP2uVSNUwWuXEyXN3cH75u/9q74uXxTZvT5KkUIM5iwBeUNXlIwoJwh5Dimew== X-Received: by 2002:a17:906:50b:b0:a52:2a91:eebd with SMTP id j11-20020a170906050b00b00a522a91eebdmr728206eja.75.1712846852603; Thu, 11 Apr 2024 07:47:32 -0700 (PDT) Received: from positronik4lide.. ([87.122.56.49]) by smtp.gmail.com with ESMTPSA id lo17-20020a170906fa1100b00a466af74ef2sm816835ejb.2.2024.04.11.07.47.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Apr 2024 07:47:32 -0700 (PDT) From: jmeng@redhat.com To: dev@openvswitch.org, i.maximets@ovn.org, echaudro@redhat.com, ktraynor@redhat.com, aconole@redhat.com, rjarry@redhat.com Date: Thu, 11 Apr 2024 16:47:15 +0200 Message-Id: <20240411144718.1921869-4-jmeng@redhat.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240411144718.1921869-1-jmeng@redhat.com> References: <20240411144718.1921869-1-jmeng@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v8 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 --- NEWS | 3 +++ lib/unixctl.c | 6 +++--- lib/unixctl.h | 2 +- tests/ovs-vswitchd.at | 5 +++++ utilities/ovs-appctl.c | 32 ++++++++++++++++++++++++++++---- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index f18238159..52cadbe0d 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ 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. + E.g. members of objects and elements of arrays are printed one per line, + with indentation. - Python: * Added support for choosing the output format, e.g. 'json' or 'text'. diff --git a/lib/unixctl.c b/lib/unixctl.c index 18638d86a..4bb6bbe7f 100644 --- a/lib/unixctl.c +++ b/lib/unixctl.c @@ -572,8 +572,8 @@ unixctl_client_create(const char *path, struct jsonrpc **client) * '*err' if not NULL. */ int unixctl_client_transact(struct jsonrpc *client, const char *command, int argc, - char *argv[], enum ovs_output_fmt fmt, char **result, - char **err) + char *argv[], enum ovs_output_fmt fmt, int fmt_flags, + char **result, char **err) { struct jsonrpc_msg *request, *reply; struct json **json_args, *params, *output_src; @@ -604,7 +604,7 @@ unixctl_client_transact(struct jsonrpc *client, const char *command, int argc, if (fmt == OVS_OUTPUT_FMT_TEXT && output_src->type == JSON_STRING) { *output_dst = xstrdup(json_string(output_src)); } else if (fmt == OVS_OUTPUT_FMT_JSON) { - *output_dst = json_to_string(output_src, 0); + *output_dst = json_to_string(output_src, fmt_flags); } else { VLOG_WARN("%s: unexpected %s type in JSON rpc reply: %s", jsonrpc_get_name(client), diff --git a/lib/unixctl.h b/lib/unixctl.h index b30bcf092..c49f0c658 100644 --- a/lib/unixctl.h +++ b/lib/unixctl.h @@ -39,7 +39,7 @@ int unixctl_client_create(const char *path, struct jsonrpc **client); int unixctl_client_transact(struct jsonrpc *client, const char *command, int argc, char *argv[], - enum ovs_output_fmt fmt, + enum ovs_output_fmt fmt, int fmt_flags, char **result, char **error); /* Command registration. */ diff --git a/tests/ovs-vswitchd.at b/tests/ovs-vswitchd.at index 32ca2c6e7..5683896ef 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-format":"plain","reply":"$ovs_version\n"}]) +AT_CHECK_UNQUOTED([ovs-appctl --format json --pretty version], [0], [dnl +{ + "reply": "$ovs_version\n", + "reply-format": "plain"}]) + AT_CLEANUP diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c index 4d4503597..9872d5bde 100644 --- a/utilities/ovs-appctl.c +++ b/utilities/ovs-appctl.c @@ -26,6 +26,7 @@ #include "daemon.h" #include "dirs.h" #include "openvswitch/dynamic-string.h" +#include "openvswitch/json.h" #include "jsonrpc.h" #include "process.h" #include "timeval.h" @@ -39,6 +40,7 @@ static void usage(void); /* Parsed command line args. */ struct cmdl_args { enum ovs_output_fmt format; + int format_flags; char *target; }; @@ -74,8 +76,8 @@ main(int argc, char *argv[]) if (!svec_is_empty(&opt_argv)) { error = unixctl_client_transact(client, "set-options", opt_argv.n, opt_argv.names, - args->format, &cmd_result, - &cmd_error); + args->format, 0, + &cmd_result, &cmd_error); if (error) { ovs_fatal(error, "%s: transaction error", args->target); @@ -98,7 +100,9 @@ main(int argc, char *argv[]) cmd_argc = argc - optind; cmd_argv = cmd_argc ? argv + optind : NULL; error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv, - args->format, &cmd_result, &cmd_error); + args->format, args->format_flags, + &cmd_result, &cmd_error); + if (error) { ovs_fatal(error, "%s: transaction error", args->target); } @@ -144,6 +148,11 @@ 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\ ('text', by default)\n\ + --pretty By default, JSON in output is printed as compactly as\n\ + possible. This option causes JSON in output to be\n\ + printed in a more readable fashion. Members of objects\n\ + and elements of arrays are printed one per line, with\n\ + indentation.\n\ -h, --help Print this helpful information\n\ -V, --version Display ovs-appctl version information\n", program_name, program_name); @@ -155,6 +164,7 @@ cmdl_args_create(void) { struct cmdl_args *args = xmalloc(sizeof *args); args->format = OVS_OUTPUT_FMT_TEXT; + args->format_flags = 0; args->target = NULL; return args; @@ -171,7 +181,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'}, @@ -179,6 +190,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, @@ -188,6 +200,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; @@ -230,6 +243,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); @@ -259,6 +276,13 @@ parse_command_line(int argc, char *argv[]) "(use --help for help)"); } + if (pretty) { + if (args->format != OVS_OUTPUT_FMT_JSON) { + ovs_fatal(0, "--pretty is supported with --format json only"); + } + args->format_flags |= JSSF_PRETTY | JSSF_SORT; + } + if (!args->target) { args->target = xstrdup("ovs-vswitchd"); }