From patchwork Fri Apr 12 07:26:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakob Meng X-Patchwork-Id: 1922882 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=DIZWmWlj; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (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 4VG7Rv1DSxz1yYX for ; Fri, 12 Apr 2024 17:27:06 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 51A84826DE; Fri, 12 Apr 2024 07:27:04 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id zpts-zaN_TNR; Fri, 12 Apr 2024 07:27:00 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 2A5C7825FE Authentication-Results: smtp1.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=DIZWmWlj Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 2A5C7825FE; Fri, 12 Apr 2024 07:27:00 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CFD16C0DCF; Fri, 12 Apr 2024 07:26:59 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id ED6BAC0DD4 for ; Fri, 12 Apr 2024 07:26:58 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id D67DF41FC0 for ; Fri, 12 Apr 2024 07:26:58 +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 x-nC4J0vbwMW for ; Fri, 12 Apr 2024 07:26:54 +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 smtp4.osuosl.org 6FBAB41FAC Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 6FBAB41FAC Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DIZWmWlj Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 6FBAB41FAC for ; Fri, 12 Apr 2024 07:26:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712906813; 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=7DDsL+MAgdF9rRltIhoSyy7bNZBxiaem0V4ZyFXLO/o=; b=DIZWmWljzIgyZqMeQr3dybrbh5bJtyiq7Euz00/r80gGEck2Oh+ovwi/eMROOILfBBLVQ3 EUJeuAxmg7/e6JrjsyRbUQ2H2eT6FbtEF4NlVvcL4nFyweLWfGhgX230xXQPoyKTe4MaL9 tDVWues78rlZ1acASZcQM6teDC6DG/A= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-207--M1LRMb1OHGnb3Wm5sSmBQ-1; Fri, 12 Apr 2024 03:26:50 -0400 X-MC-Unique: -M1LRMb1OHGnb3Wm5sSmBQ-1 Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-a5190b1453fso34349766b.2 for ; Fri, 12 Apr 2024 00:26:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712906809; x=1713511609; 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=7DDsL+MAgdF9rRltIhoSyy7bNZBxiaem0V4ZyFXLO/o=; b=rSptQY5037/TtJ5tSjjJXp1GRNgKj/W9vnRj5clKvzCLORilAn+YWA2EpgzgCIQuKq WgEVm7mYh0h1M3LGr99Lel3ZTaY53WrXHw+fM4EcqZAzEVdtuk5VmIxCWQQWqOhnkHMO m51EEnCiW8St5l7PLyQAc8Wkorm+emMFmuTGO1ZpOT/V8+P91J0BY6FC5t4Y94jtzArE +kJuEppjq8YL8xsu9h2lU+UYmiQzZjoxF39Jaev9fAqlXkseGks/fK1dVmMofrCzHThI Hx0rTrCK1QGm5pdUtfeOJw/nKWLDeuFfi/i5xdM/EGOQ7eOt3GJsKZpDdu2A4U5UaHyJ 54bw== X-Gm-Message-State: AOJu0YzJOPgA0j70/xcN/g4arImP9aCykeTFFkinnDksdKzAkmDg9Zrm xzBmOfZm/qZJFLrAbTidzinhrT1FueORKVBKOVIZumNOU5wGhbsak3c6/sB/YMDuKCH0ejHGAnl gZKpJKARsE4+dVYaP0UbwtOK/ucY42RySidl1wPh2edtRXFmVzpY9FU6STCt4YZLmej5vW0r90e IOCU766p61fLOWT7IKgP62phL7NZZv X-Received: by 2002:a17:906:b12:b0:a52:243f:5bb7 with SMTP id u18-20020a1709060b1200b00a52243f5bb7mr859227ejg.32.1712906809427; Fri, 12 Apr 2024 00:26:49 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEnXi7wTmi9SP30OUq0/aWiKdYxV3WFzXmmAPvdwNO0J1kPOumuGPyIkoqWBCHuzniOm3fKpw== X-Received: by 2002:a17:906:b12:b0:a52:243f:5bb7 with SMTP id u18-20020a1709060b1200b00a52243f5bb7mr859211ejg.32.1712906809109; Fri, 12 Apr 2024 00:26:49 -0700 (PDT) Received: from positronik4lide.. ([87.122.58.150]) by smtp.gmail.com with ESMTPSA id t2-20020a1709064f0200b00a51dd500071sm1502373eju.169.2024.04.12.00.26.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Apr 2024 00:26:48 -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: Fri, 12 Apr 2024 09:26:35 +0200 Message-Id: <20240412072638.712622-4-jmeng@redhat.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240412072638.712622-1-jmeng@redhat.com> References: <20240412072638.712622-1-jmeng@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v9 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..67cf26418 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, + unsigned 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..5a08a1bd1 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, unsigned 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..29a0de2ee 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; + unsigned 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"); }