[Libguestfs] [PATCH v5 2/2] fish: add journal-view command (RHBZ#988100)
Pino Toscano
ptoscano at redhat.com
Wed Sep 2 10:20:27 UTC 2015
In data lunedì 31 agosto 2015 15:07:37, Maros Zatko ha scritto:
> Lets user view journald log from VM in a similar format as journalctl
> uses.
"Let the user view the journald log from a guest, with a format similar
to what journalctl uses."
>
> Fixes RFE: journal reader in guestfish
> ---
> cat/log.c | 4 +++
> fish/journal.c | 3 +-
> generator/Makefile.am | 6 ++--
> generator/actions.ml | 22 ++++++++++++
> generator/journal.ml | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++
> generator/main.ml | 3 ++
> 6 files changed, 131 insertions(+), 4 deletions(-)
> create mode 100644 generator/journal.ml
>
> diff --git a/cat/log.c b/cat/log.c
> index f05eae0..157ee55 100644
> --- a/cat/log.c
> +++ b/cat/log.c
> @@ -36,6 +36,7 @@
>
> #include "guestfs.h"
> #include "options.h"
> +#include "journal.h"
>
> /* Currently open libguestfs handle. */
> guestfs_h *g;
> @@ -279,6 +280,9 @@ do_log_journal (void)
> if (guestfs_journal_open (g, JOURNAL_DIR) == -1)
> return -1;
>
> + if (journal_view ("~3axv") == -1)
> + return -1;
> +
> if (guestfs_journal_close (g) == -1)
> return -1;
>
This should be part of patch #1 if possible.
> diff --git a/fish/journal.c b/fish/journal.c
> index 9afdf60..579a1d1 100644
> --- a/fish/journal.c
> +++ b/fish/journal.c
> @@ -83,9 +83,8 @@ lookup_field (char field)
> int
> journal_view (const char *fields)
> {
> - int r;
> int errors = 0;
> - while ((r = guestfs_journal_next(g)) > 0) {
> + while (guestfs_journal_next(g) > 0) {
> CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
> int64_t ts;
> int priority = LOG_INFO;
Ditto.
> diff --git a/generator/Makefile.am b/generator/Makefile.am
> index a3fe50d..bd466c2 100644
> --- a/generator/Makefile.am
> +++ b/generator/Makefile.am
> @@ -37,6 +37,7 @@ sources = \
> haskell.ml \
> java.ml \
> lua.ml \
> + journal.ml \
> main.ml \
> ocaml.ml \
> optgroups.ml \
> @@ -60,13 +61,14 @@ sources = \
> objects = \
> types.cmo \
> utils.cmo \
> + pr.cmo \
> + docstrings.cmo \
> + journal.cmo \
> actions.cmo \
> structs.cmo \
> optgroups.cmo \
> prepopts.cmo \
> events.cmo \
> - pr.cmo \
> - docstrings.cmo \
> checks.cmo \
> c.cmo \
> xdr.cmo \
> diff --git a/generator/actions.ml b/generator/actions.ml
> index 13c8bc8..e914fd3 100644
> --- a/generator/actions.ml
> +++ b/generator/actions.ml
> @@ -21,6 +21,8 @@
> open Types
> open Utils
>
> +open Journal
> +
> (* Default settings for all action fields. So we copy and override
> * this struct by writing '{ defaults with name = &c }'
> *)
> @@ -12897,6 +12899,26 @@ environment variable.
> See also L</hexdump>." };
>
> { defaults with
> + name = "journal_view";
> + shortdesc = "view journald log";
> + longdesc = " journal-view [FORMAT]
> +
> +View journald log in format similar to journalctl.
"journalctl" could be linkified, so L<journalctl(1)>.
> +
> +=over
> +
> +"
> +^ (Journal.ops_to_pod_string ()) ^
> +"
> +=back
> +
> +Default format is C<~3axv>
"The default format is C<~3axv>."
> +
> +For fields description see C<man SYSTEMD.JOURNAL-FIELDS>
There's the proper format for linking man pages, so it should be
L<systemd.journal-fields(7)>.
> +
> +Use C<journal-open> first." };
C<guestfs_journal_open> here, so it gets proper linking.
> +
> + { defaults with
> name = "lcd";
> shortdesc = "change working directory";
> longdesc = " lcd directory
> diff --git a/generator/journal.ml b/generator/journal.ml
> new file mode 100644
> index 0000000..46d93cd
> --- /dev/null
> +++ b/generator/journal.ml
> @@ -0,0 +1,97 @@
> +(* libguestfs
> + * Copyright (C) 2015 Red Hat Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + *)
> +
> +(* Please read generator/README first. *)
> +
> +open Printf
> +
> +open String
> +open Docstrings
> +open Pr
> +
> +open Char
> +open List
I guess you don't need to open List, if later you always use it like
List.foo.
> +
> +(* Arguments used by journal-view command *)
> +
> +type op_type = Options of (char * string) list;; (* option, option name*)
What is Options? I cannot find it neither in the OCaml standard library
nor in the generator own types...
As a style note, usually ;; at the end of top-level statements are not
used in libguestfs' code.
> +let op = Options [
> + (* Trusted fields *)
> + ('a', "_PID");
> + ('b', "_UID");
> + ('c', "_GID");
> + ('d', "_COMM");
> + ('e', "_EXE");
> + ('f', "_CMDLINE");
> + ('g', "_CAP_EFFECTIVE");
> + ('h', "_AUDIT_SESSION");
> + ('i', "_AUDIT_LOGINUID");
> + ('j', "_SYSTEMD_CGROUP");
> + ('k', "_SYSTEMD_SESSION");
> + ('l', "_SYSTEMD_UNIT");
> + ('m', "_SYSTEMD_USER_UNIT");
> + ('n', "_SYSTEMD_OWNER_UID");
> + ('o', "_SYSTEMD_SLICE");
> + ('p', "_SELINUX_CONTEXT");
> + ('q', "_SOURCE_REALTIME_TIMESTAMP");
> + ('r', "_BOOT_ID");
> + ('s', "_MACHINE_ID");
> + ('t', "_HOSTNAME");
> + ('u', "_TRANSPORT");
> + (* User fields *)
> + ('v', "MESSAGE");
> + ('w', "MESSAGE_ID");
> + ('x', "PRIORITY");
> + ('y', "CODE_FILE");
> + ('z', "CODE_LINE");
> + ('0', "CODE_FUNC");
> + ('1', "ERRNO");
> + ('2', "SYSLOG_FACILITY");
> + ('3', "SYSLOG_IDENTIFIER");
> + ('4', "SYSLOG_PID");
> + ('~', "timestamp")
> +];;
> +
> +let deopt x = match x with Options y -> y;;
Considering you always call deopt on 'op', declaring it as
(char * string) list should be enough, I guess.
> +let string_list_to_string s = List.fold_left (fun a b -> a ^ b) "" s;;
Using String.concat would make it easier to read/understand... although
seems not used at all.
> +let ops_to_pod_string () =
> + List.fold_left (fun a b -> a ^ b) ""
String.concat here would be easier.
> + (List.map (fun (a,b) -> "=item " ^ escaped a ^ " " ^ b ^ "\n\n")
> + (deopt op));;
> +
> +let ops_to_c_array arrname () =
> + let decl = "static const char *const " ^ arrname ^ "[] = {\n" in
Considering it does not change, you could put the array opening and
closing directly in the printed C code.
> + decl ^ String.concat ",\n"
> + (List.map (fun (a,b) -> " \"" ^ escaped a ^ "\", \"" ^ b ^ "\"")
> + (deopt op)) ^ "\n};";;
IMHO this could be inline in generate_journal_h, just using List.iter
to print each line in the array.
> +let generate_journal_h () =
> + generate_header CStyle LGPLv2plus;
> + pr "#include <config.h>\n";
> + pr "\n";
> + pr "#ifndef JOURNAL_H\n";
> + pr "#define JOURNAL_H\n";
> + pr "\n";
> + pr "%s\n" (ops_to_c_array "journal_fields" ());
> + pr "\n";
> + pr "/* in journal.c */\n";
> + pr "extern int journal_view (const char *fields);\n";
> + pr "#endif /* JOURNAL_H */\n";
The generated code here could be better: instead of generating an array
each field code (as string) and name one after the other, have a list
of structs:
static const struct JournalField {
char field;
const char *name;
} fields[] = {
{ 'a', "_PID" },
...
};
>From what I see in these patches, it seems like the array with fields
is just an implementation detail of journal_view, and thus not worth
exposing in journal.h. Maybe generate a journal-fields.h (or even .c)
to include directly in journal.c, so journal.h can stay as
non-generated file.
Thanks,
--
Pino Toscano
More information about the Libguestfs
mailing list