src/libotutil/ot-variant-utils.h \
src/libotutil/ot-gio-utils.c \
src/libotutil/ot-gio-utils.h \
- src/libotutil/ot-log-utils.c \
- src/libotutil/ot-log-utils.h \
src/libotutil/ot-gpg-utils.c \
src/libotutil/ot-gpg-utils.h \
src/libotutil/otutil.c \
#include "ostree-linuxfsutil.h"
#include "libglnx.h"
-#define OSTREE_VARRELABEL_ID "da679b08acd34504b789d96f818ea781"
-#define OSTREE_CONFIGMERGE_ID "d3863baec13e4449ab0384684a8af3a7"
#ifdef HAVE_LIBSYSTEMD
+#define OSTREE_VARRELABEL_ID SD_ID128_MAKE(da,67,9b,08,ac,d3,45,04,b7,89,d9,6f,81,8e,a7,81)
+#define OSTREE_CONFIGMERGE_ID SD_ID128_MAKE(d3,86,3b,ae,c1,3e,44,49,ab,03,84,68,4a,8a,f3,a7)
#define OSTREE_DEPLOYMENT_COMPLETE_ID SD_ID128_MAKE(dd,44,0e,3e,54,90,83,b6,3d,0e,fc,7d,c1,52,55,f1)
#endif
cancellable, error))
return glnx_prefix_error (error, "While computing configuration diff");
- ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID,
- "Copying /etc changes: %u modified, %u removed, %u added",
- modified->len,
- removed->len,
- added->len);
+ { g_autofree char *msg =
+ g_strdup_printf ("Copying /etc changes: %u modified, %u removed, %u added",
+ modified->len, removed->len, added->len);
+#ifdef HAVE_LIBSYSTEMD
+ sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_CONFIGMERGE_ID),
+ "MESSAGE=%s", msg,
+ "ETC_N_MODIFIED=%u", modified->len,
+ "ETC_N_REMOVED=%u", removed->len,
+ "ETC_N_ADDED=%u", added->len,
+ NULL);
+#endif
+ _ostree_sysroot_emit_journal_msg (sysroot, msg);
+ }
glnx_fd_close int orig_etc_fd = -1;
if (!glnx_opendirat (merge_deployment_dfd, "usr/etc", TRUE, &orig_etc_fd, error))
if (!deployment_var_labeled)
{
- ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID,
- "Relabeling /var (no stamp file '%s' found)",
- selabeled);
+ { g_autofree char *msg =
+ g_strdup_printf ("Relabeling /var (no stamp file '%s' found)", selabeled);
+#ifdef HAVE_LIBSYSTEMD
+ sd_journal_send ("MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(OSTREE_VARRELABEL_ID),
+ "MESSAGE=%s", msg,
+ NULL);
+#endif
+ _ostree_sysroot_emit_journal_msg (sysroot, msg);
+ }
g_autoptr(GFile) deployment_var_path = ot_fdrel_to_gfile (os_deploy_dfd, "var");
if (!selinux_relabel_dir (sysroot, sepolicy,
"OSTREE_SYNCFS_EXTRA_MSEC=%" G_GUINT64_FORMAT, syncstats.extra_syncfs_msec,
NULL);
#endif
- if (!ot_stdout_is_journal ())
- g_print ("%s\n", msg);
+ _ostree_sysroot_emit_journal_msg (self, msg);
}
if (!_ostree_sysroot_bump_mtime (self, error))
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_DIR "/run/ostree/deployment-state/"
#define _OSTREE_SYSROOT_DEPLOYMENT_RUNSTATE_FLAG_DEVELOPMENT "unlocked-development"
+void
+_ostree_sysroot_emit_journal_msg (OstreeSysroot *self,
+ const char *msg);
+
gboolean
_ostree_sysroot_read_boot_loader_configs (OstreeSysroot *self,
int bootversion,
*/
typedef struct {
GObjectClass parent_class;
+
+ /* Signals */
+ void (*journal_msg) (OstreeSysroot *sysroot,
+ const char *msg);
} OstreeSysrootClass;
+enum {
+ JOURNAL_MSG_SIGNAL,
+ LAST_SIGNAL,
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
enum {
PROP_0,
"",
G_TYPE_FILE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * OstreeSysroot::journal-msg:
+ * @self: Self
+ * @msg: Human-readable string (should not contain newlines)
+ *
+ * libostree will log to the journal various events, such as the /etc merge
+ * status, and transaction completion. Connect to this signal to also
+ * synchronously receive the text for those messages. This is intended to be
+ * used by command line tools which link to libostree as a library.
+ *
+ * Currently, the structured data is only available via the systemd journal.
+ *
+ * Since: 2017.10
+ */
+ signals[JOURNAL_MSG_SIGNAL] =
+ g_signal_new ("journal-msg",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (OstreeSysrootClass, journal_msg),
+ NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
return TRUE;
}
+void
+_ostree_sysroot_emit_journal_msg (OstreeSysroot *self,
+ const char *msg)
+{
+ g_signal_emit (self, signals[JOURNAL_MSG_SIGNAL], 0, msg);
+}
+
gboolean
_ostree_sysroot_parse_deploy_path_name (const char *name,
char **out_csum,
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2016 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include <gio/gio.h>
-
-#include <string.h>
-
-#include "otutil.h"
-#include "libglnx.h"
-
-#ifdef HAVE_LIBSYSTEMD
-#define SD_JOURNAL_SUPPRESS_LOCATION
-#include <systemd/sd-journal.h>
-#endif
-#include <glib-unix.h>
-
-/**
- * ot_log_structured:
- * @message: Text message to send
- * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
- *
- * Log structured data in an operating-system specific fashion. The
- * parameter @opts should be an array of UTF-8 KEY=VALUE strings.
- * This function does not support binary data. See
- * http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
- * for more information about fields that can be used on a systemd
- * system.
- */
-static void
-ot_log_structured (const char *message,
- const char *const *keys)
-{
-#ifdef HAVE_LIBSYSTEMD
- const char *const*iter;
- g_autofree char *msgkey = NULL;
- guint i, n_opts;
- struct iovec *iovs;
-
- for (n_opts = 0, iter = keys; *iter; iter++, n_opts++)
- ;
-
- n_opts++; /* Add one for MESSAGE= */
- iovs = g_alloca (sizeof (struct iovec) * n_opts);
-
- for (i = 0, iter = keys; *iter; iter++, i++) {
- iovs[i].iov_base = (char*)keys[i];
- iovs[i].iov_len = strlen (keys[i]);
- }
- g_assert(i == n_opts-1);
- msgkey = g_strconcat ("MESSAGE=", message, NULL);
- iovs[i].iov_base = msgkey;
- iovs[i].iov_len = strlen (msgkey);
-
- // The code location isn't useful since we're wrapping
- sd_journal_sendv (iovs, n_opts);
-#else
- g_print ("%s\n", message);
-#endif
-}
-
-/**
- * ot_stdout_is_journal:
- *
- * Use this function when you want your code to behave differently
- * depeneding on whether your program was started as a systemd unit,
- * or e.g. interactively at a terminal.
- *
- * Returns: %TRUE if stdout is (probably) connnected to the systemd journal
- */
-gboolean
-ot_stdout_is_journal (void)
-{
- static gsize initialized;
- static gboolean stdout_is_socket;
-
- if (g_once_init_enter (&initialized))
- {
- guint64 pid = (guint64) getpid ();
- g_autofree char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid);
- char buf[1024];
- ssize_t bytes_read;
-
- if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1)
- {
- buf[bytes_read] = '\0';
- stdout_is_socket = g_str_has_prefix (buf, "socket:");
- }
- else
- stdout_is_socket = FALSE;
-
- g_once_init_leave (&initialized, TRUE);
- }
-
- return stdout_is_socket;
-}
-
-/**
- * gs_log_structured_print:
- * @message: A message to log
- * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data
- *
- * Like gs_log_structured(), but also print to standard output (if it
- * is not already connected to the system log).
- */
-static void
-ot_log_structured_print (const char *message,
- const char *const *keys)
-{
- ot_log_structured (message, keys);
-
-#ifdef HAVE_LIBSYSTEMD
- if (!ot_stdout_is_journal ())
- g_print ("%s\n", message);
-#endif
-}
-
-/**
- * ot_log_structured_print_id_v:
- * @message_id: A unique MESSAGE_ID
- * @format: A format string
- *
- * The provided @message_id is a unique MESSAGE_ID (see <ulink url="http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html"> for more information).
- *
- * This function otherwise acts as ot_log_structured_print(), taking
- * @format as a format string.
- */
-void
-ot_log_structured_print_id_v (const char *message_id,
- const char *format,
- ...)
-{
- const char *key0 = glnx_strjoina ("MESSAGE_ID=", message_id);
- const char *keys[] = { key0, NULL };
- g_autofree char *msg = NULL;
- va_list args;
-
- va_start (args, format);
- msg = g_strdup_vprintf (format, args);
- va_end (args);
-
- ot_log_structured_print (msg, (const char *const *)keys);
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2016 Colin Walters <walters@verbum.org>.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#pragma once
-
-#include "ot-unix-utils.h"
-
-G_BEGIN_DECLS
-
-gboolean ot_stdout_is_journal (void);
-
-void ot_log_structured_print_id_v (const char *message_id,
- const char *format,
- ...) G_GNUC_PRINTF(2, 3);
-
-G_END_DECLS
#include <ot-variant-utils.h>
#include <ot-checksum-utils.h>
#include <ot-gpg-utils.h>
-#include <ot-log-utils.h>
#include <ot-checksum-instream.h>
void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED;
return TRUE;
}
+static void
+on_sysroot_journal_msg (OstreeSysroot *sysroot,
+ const char *msg)
+{
+ g_print ("%s\n", msg);
+}
+
gboolean
ostree_admin_option_context_parse (GOptionContext *context,
const GOptionEntry *main_entries,
sysroot_path = g_file_new_for_path (opt_sysroot);
g_autoptr(OstreeSysroot) sysroot = ostree_sysroot_new (sysroot_path);
+ g_signal_connect (sysroot, "journal-msg", G_CALLBACK (on_sysroot_journal_msg), NULL);
if (flags & OSTREE_ADMIN_BUILTIN_FLAG_SUPERUSER)
{