[Libguestfs] [PATCH v5 2/2] fish: add journal-view command (RHBZ#988100)

Maros Zatko
Mon, 31 Aug 2015 13:07:37 -0000

Lets user view journald log from VM in a similar format as 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;

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;
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.
+
+=over
+
+"
+^ (Journal.ops_to_pod_string ()) ^
+"
+=back
+
+Default format is C<~3axv>
+
+For fields description see C<man SYSTEMD.JOURNAL-FIELDS>
+
+Use C<journal-open> first." };
+
+  { 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
+
+(* Arguments used by journal-view command *)
+
+type op_type = Options of (char * string) list;;       (* option, option name*)
+
+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;;
+
+let string_list_to_string s = List.fold_left (fun a b -> a ^ b) ""
s;;
+
+let ops_to_pod_string () +  List.fold_left (fun a b -> a ^ b) ""
+    (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
+  decl ^ String.concat ",\n"
+    (List.map (fun (a,b) -> "  \"" ^ escaped a ^
"\", \"" ^ b ^ "\"")
+      (deopt op)) ^ "\n};";;
+
+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";
diff --git a/generator/main.ml b/generator/main.ml
index 1e0e7d6..639920d 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -46,6 +46,7 @@ open Golang
 open Bindtests
 open Errnostring
 open Customize
+open Journal

 let perror msg = function
   | Unix_error (err, _, _) ->
@@ -212,6 +213,8 @@ Run it from the top source directory using the command
   output_to "customize/customize-synopsis.pod"
generate_customize_synopsis_pod;
   output_to "customize/customize-options.pod"
generate_customize_options_pod;

+  output_to "fish/journal.h" generate_journal_h;
+
   (* Generate the list of files generated -- last. *)
   printf "generated %d lines of code\n" (get_lines_generated ());
   let files = List.sort compare (get_files_generated ()) in
--
1.9.3