Move MOTD population into the daemon

This allows it to be refreshed anytime the daemon updates rather
than once a day by a systemd job.

As part of this change, remove the logging from `fwupdmgr` which
was only used for motd purposes.
This commit is contained in:
Mario Limonciello 2020-01-13 14:11:43 -06:00 committed by Mario Limonciello
parent eb442ea9a5
commit d81ea2e3fc
15 changed files with 159 additions and 85 deletions

View File

@ -46,7 +46,6 @@ _fwupdmgr_opts=(
'--show-all-devices'
'--sign'
'--filter'
'--log'
'--disable-ssl-strict'
)

View File

@ -22,3 +22,6 @@ IdleTimeout=7200
# If set to FuValue, FuValue domain (same as --domain-verbose=FuValue)
# If set to *, all domains (same as --verbose)
VerboseDomains=
# Update the message of the day (MOTD) on device and metadata changes
UpdateMotd=true

View File

@ -6,6 +6,8 @@ Before=display-manager.service
[Service]
Type=dbus
RuntimeDirectory=@motd_dir@
RuntimeDirectoryPreserve=yes
BusName=org.freedesktop.fwupd
ExecStart=@libexecdir@/fwupd/fwupd
StateDirectory=@package_name@

View File

@ -91,6 +91,7 @@ endif
if (get_option('systemd') or get_option('elogind')) and build_daemon
con2 = configuration_data()
con2.set('libexecdir', libexecdir)
con2.set('motd_dir', motd_dir)
# replace @libexecdir@
configure_file(

View File

@ -5,9 +5,7 @@ After=network.target network-online.target systemd-networkd.service NetworkManag
[Service]
Type=oneshot
RuntimeDirectory=@motd_dir@
CacheDirectory=fwupdmgr
RuntimeDirectoryPreserve=yes
StandardError=null
DynamicUser=yes
RestrictAddressFamilies=AF_NETLINK AF_UNIX AF_INET AF_INET6
@ -17,4 +15,3 @@ ProtectControlGroups=yes
RestrictRealtime=yes
SuccessExitStatus=2
ExecStart=@bindir@/fwupdmgr refresh --no-metadata-check
@dynamic_options@

View File

@ -1,35 +1,20 @@
motd_file = '85-fwupd'
motd_dir = 'motd.d'
fwupdmgr_path = join_paths (bindir, 'fwupdmgr')
motd_fullpath = join_paths ('/run', motd_dir, motd_file)
con2 = configuration_data()
con2.set('bindir', bindir)
con2.set('motd_file', motd_file)
con2.set('motd_dir', motd_dir)
con2.set('motd_fullpath', motd_fullpath)
if get_option('systemd')
install_data(['fwupd-refresh.timer'],
install_dir: systemdunitdir)
install_data(['fwupd-refresh.preset'],
install_dir: systemdsystempresetdir)
dynamic_options = []
if systemd.version().version_compare('>= 243')
dynamic_options += 'ExecStart=' + fwupdmgr_path + ' get-updates --log ' + motd_file
else
dynamic_options += '# motd population disabled; requires systemd v243 or later'
endif
con2.set('dynamic_options', '\n'.join(dynamic_options))
configure_file(
input : 'fwupd-refresh.service.in',
output : 'fwupd-refresh.service',
configuration : con2,
install: true,
install_data(['fwupd-refresh.service'],
install_dir: systemdunitdir)
motd_fullpath = join_paths ('/run', motd_dir, motd_file)
else
motd_fullpath = join_paths (localstatedir, motd_dir, motd_file)
endif
con2 = configuration_data()
con2.set('motd_fullpath', motd_fullpath)
# This file is only used in Ubuntu, which chooses to use update-motd instead
# of sourcing /run/motd.d/*
# See https://bugs.launchpad.net/ubuntu/+source/pam/+bug/399071

View File

@ -397,6 +397,12 @@ endif
conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
conf.set_quoted('PACKAGE_NAME', meson.project_name())
conf.set_quoted('VERSION', meson.project_version())
motd_file = '85-fwupd'
motd_dir = 'motd.d'
conf.set_quoted('MOTD_FILE', motd_file)
conf.set_quoted('MOTD_DIR', motd_dir)
configure_file(
output : 'config.h',
configuration : conf

View File

@ -7,6 +7,7 @@ plugins/uefi/fu-plugin-uefi.c
plugins/uefi/fu-uefi-tool.c
src/fu-agent.c
src/fu-debug.c
src/fu-engine-helper.c
src/fu-main.c
src/fu-offline.c
src/fu-progressbar.c

View File

@ -33,6 +33,7 @@ struct _FuConfig
guint64 archive_size_max;
guint idle_timeout;
gchar *config_file;
gboolean update_motd;
};
G_DEFINE_TYPE (FuConfig, fu_config, G_TYPE_OBJECT)
@ -126,6 +127,12 @@ fu_config_reload (FuConfig *self, GError **error)
if (domains != NULL && domains[0] != '\0')
g_setenv ("FWUPD_VERBOSE", domains, TRUE);
/* whether to update the motd on changes */
self->update_motd = g_key_file_get_boolean (keyfile,
"fwupd",
"UpdateMotd",
NULL);
return TRUE;
}
@ -223,6 +230,13 @@ fu_config_get_approved_firmware (FuConfig *self)
return self->approved_firmware;
}
gboolean
fu_config_get_update_motd (FuConfig *self)
{
g_return_val_if_fail (FU_IS_CONFIG (self), FALSE);
return self->update_motd;
}
static void
fu_config_class_init (FuConfigClass *klass)
{

View File

@ -26,3 +26,4 @@ guint fu_config_get_idle_timeout (FuConfig *self);
GPtrArray *fu_config_get_blacklist_devices (FuConfig *self);
GPtrArray *fu_config_get_blacklist_plugins (FuConfig *self);
GPtrArray *fu_config_get_approved_firmware (FuConfig *self);
gboolean fu_config_get_update_motd (FuConfig *self);

81
src/fu-engine-helper.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2020 Mario Limonciello <mario.limonciello@dell.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#define G_LOG_DOMAIN "FuEngine"
#include "config.h"
#include <glib/gi18n.h>
#include "fu-engine.h"
#include "fu-engine-helper.h"
gboolean
fu_engine_update_motd (FuEngine *self, GError **error)
{
guint upgrade_count = 0;
g_autoptr(GPtrArray) devices = NULL;
g_autoptr(GString) str = NULL;
g_autofree gchar *target = NULL;
/* get devices from daemon, we even want to know if it's nothing */
devices = fu_engine_get_devices (self, NULL);
if (devices != NULL) {
for (guint i = 0; i < devices->len; i++) {
FwupdDevice *dev = g_ptr_array_index (devices, i);
g_autoptr(GPtrArray) rels = NULL;
/* get the releases for this device */
rels = fu_engine_get_upgrades (self,
fwupd_device_get_id (dev),
NULL);
if (rels == NULL)
continue;
upgrade_count++;
}
}
/* If running under systemd unit, use the directory as a base */
if (g_getenv ("RUNTIME_DIRECTORY") != NULL) {
target = g_build_filename (g_getenv ("RUNTIME_DIRECTORY"),
PACKAGE_NAME,
MOTD_FILE,
NULL);
/* otherwise use the cache directory */
} else {
g_autofree gchar *directory = fu_common_get_path (FU_PATH_KIND_CACHEDIR_PKG);
target = g_build_filename (directory, MOTD_DIR, MOTD_FILE, NULL);
}
/* create the directory and file, even if zero devices; we want an empty file then */
if (!fu_common_mkdir_parent (target, error))
return FALSE;
if (upgrade_count == 0) {
g_autoptr(GFile) file = g_file_new_for_path (target);
g_autoptr(GFileOutputStream) output = NULL;
output = g_file_replace (file, NULL, FALSE,
G_FILE_CREATE_NONE,
NULL, error);
return output != NULL;
}
str = g_string_new ("");
if (upgrade_count == 1) {
g_string_append_printf (str,
_("%u device has a firmware upgrade available."),
upgrade_count);
} else {
g_string_append_printf (str,
_("%u devices have a firmware upgrade available."),
upgrade_count);
}
g_string_append_printf (str,
"\n%s\n",
_("Run `fwupdmgr get-upgrades` for more information."));
return g_file_set_contents (target, str->str, str->len, error);
}

11
src/fu-engine-helper.h Normal file
View File

@ -0,0 +1,11 @@
/*
* Copyright (C) 2020 Mario Limonciello <mario.limonciello@dell.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include "fu-engine.h"
gboolean fu_engine_update_motd (FuEngine *self,
GError **error);

View File

@ -36,6 +36,7 @@
#include "fu-device-list.h"
#include "fu-device-private.h"
#include "fu-engine.h"
#include "fu-engine-helper.h"
#include "fu-hwids.h"
#include "fu-idle.h"
#include "fu-keyring-utils.h"
@ -117,6 +118,14 @@ fu_engine_emit_changed (FuEngine *self)
{
g_signal_emit (self, signals[SIGNAL_CHANGED], 0);
fu_engine_idle_reset (self);
/* update the motd */
if (self->loaded &&
fu_config_get_update_motd (self->config)) {
g_autoptr(GError) error_local = NULL;
if (!fu_engine_update_motd (self, &error_local))
g_debug ("%s", error_local->message);
}
}
static void
@ -551,6 +560,7 @@ fu_engine_modify_config (FuEngine *self, const gchar *key, const gchar *value, G
"BlacklistPlugins",
"IdleTimeout",
"VerboseDomains",
"UpdateMotd",
NULL };
g_return_val_if_fail (FU_IS_ENGINE (self), FALSE);
@ -1913,6 +1923,10 @@ fu_engine_install_release (FuEngine *self,
if ((flags & FWUPD_INSTALL_FLAG_NO_HISTORY) == 0 &&
!fu_history_modify_device (self->history, device, error))
return FALSE;
/* make the UI update */
fu_engine_emit_changed (self);
return TRUE;
}
@ -2531,7 +2545,6 @@ fu_engine_install_blob (FuEngine *self,
/* make the UI update */
fu_engine_set_status (self, FWUPD_STATUS_IDLE);
fu_engine_emit_changed (self);
g_debug ("Updating %s took %f seconds", fu_device_get_name (device),
g_timer_elapsed (timer, NULL));
return TRUE;
@ -2867,6 +2880,9 @@ fu_engine_remote_list_changed_cb (FuRemoteList *remote_list, FuEngine *self)
&error_local))
g_warning ("Failed to reload metadata store: %s",
error_local->message);
/* make the UI update */
fu_engine_emit_changed (self);
}
#ifdef HAVE_GIO_UNIX
@ -3021,7 +3037,11 @@ fu_engine_update_metadata (FuEngine *self, const gchar *remote_id,
bytes_sig, error))
return FALSE;
}
return fu_engine_load_metadata_store (self, FU_ENGINE_LOAD_FLAG_NONE, error);
if (!fu_engine_load_metadata_store (self, FU_ENGINE_LOAD_FLAG_NONE, error))
return FALSE;
fu_engine_emit_changed (self);
return TRUE;
#else
g_set_error (error,
FWUPD_ERROR,
@ -4310,6 +4330,8 @@ fu_engine_add_device (FuEngine *self, FuDevice *device)
/* sometimes inherit flags from recent history */
fu_engine_device_inherit_history (self, device);
fu_engine_emit_changed (self);
}
static void
@ -5233,6 +5255,9 @@ fu_engine_load (FuEngine *self, FuEngineLoadFlags flags, GError **error)
fu_engine_set_status (self, FWUPD_STATUS_IDLE);
self->loaded = TRUE;
/* let clients know engine finished starting up */
fu_engine_emit_changed (self);
/* success */
return TRUE;
}

View File

@ -77,8 +77,6 @@ struct FuUtilPrivate {
FwupdDeviceFlags filter_exclude;
};
static GFileOutputStream *log_output = NULL;
static gboolean fu_util_report_history (FuUtilPrivate *priv, gchar **values, GError **error);
static gboolean fu_util_download_file (FuUtilPrivate *priv,
SoupURI *uri,
@ -2384,33 +2382,6 @@ fu_util_check_polkit_actions (GError **error)
return TRUE;
}
static void
fu_util_log_output (const gchar *str)
{
if (log_output != NULL) {
g_autoptr(GError) error_local = NULL;
if (g_output_stream_write (G_OUTPUT_STREAM (log_output),
str, strlen(str),
NULL, &error_local) <0)
g_printerr ("%s\n", error_local->message);
}
}
static void
fu_util_close_log (void)
{
if (log_output != NULL) {
g_autoptr(GError) error_local = NULL;
if (!g_output_stream_close (G_OUTPUT_STREAM (log_output),
NULL,
&error_local)) {
g_printerr ("%s\n", error_local->message);
return;
}
g_object_unref (log_output);
}
}
static void
fu_util_display_help (FuUtilPrivate *priv)
{
@ -2463,9 +2434,6 @@ main (int argc, char *argv[])
{ "assume-yes", 'y', 0, G_OPTION_ARG_NONE, &priv->assume_yes,
/* TRANSLATORS: command line option */
_("Answer yes to all questions"), NULL },
{ "log", '\0', 0, G_OPTION_ARG_STRING, &log,
/* TRANSLATORS: command line option */
_("Log output to FILE (typically for scripting use)"), NULL },
{ "sign", '\0', 0, G_OPTION_ARG_NONE, &priv->sign,
/* TRANSLATORS: command line option */
_("Sign the uploaded data with the client certificate"), NULL },
@ -2710,8 +2678,7 @@ main (int argc, char *argv[])
}
/* non-TTY consoles cannot answer questions */
if (log != NULL ||
isatty (fileno (stdout)) == 0) {
if (isatty (fileno (stdout)) == 0) {
priv->no_unreported_check = TRUE;
priv->no_metadata_check = TRUE;
priv->no_reboot_check = TRUE;
@ -2808,27 +2775,6 @@ main (int argc, char *argv[])
return EXIT_FAILURE;
}
/* configure stdout redirection */
if (log != NULL) {
g_autoptr(GFile) file = NULL;
g_autofree gchar *target_fname = NULL;
/* If running under systemd unit, use the directory as a base */
if (g_getenv ("RUNTIME_DIRECTORY") != NULL) {
target_fname = g_build_filename (g_getenv ("RUNTIME_DIRECTORY"),
log,
NULL);
} else {
target_fname = g_steal_pointer (&log);
}
file = g_file_new_for_commandline_arg (target_fname);
log_output = g_file_append_to (file, G_FILE_CREATE_NONE, NULL, &error);
if (log_output == NULL) {
g_printerr ("%s\n", error->message);
return EXIT_FAILURE;
}
g_set_print_handler (fu_util_log_output);
}
/* run the specified command */
ret = fu_util_cmd_array_run (cmd_array, priv, argv[1], (gchar**) &argv[2], &error);
if (!ret) {
@ -2841,7 +2787,6 @@ main (int argc, char *argv[])
} else {
ret = EXIT_SUCCESS;
}
fu_util_close_log ();
return ret;
}

View File

@ -137,6 +137,7 @@ fwupdtool = executable(
'fu-debug.c',
'fu-device-list.c',
'fu-engine.c',
'fu-engine-helper.c',
'fu-history.c',
'fu-idle.c',
'fu-install-task.c',
@ -205,6 +206,7 @@ executable(
'fu-debug.c',
'fu-device-list.c',
'fu-engine.c',
'fu-engine-helper.c',
'fu-history.c',
'fu-idle.c',
'fu-install-task.c',
@ -263,6 +265,7 @@ if get_option('tests')
'fu-config.c',
'fu-device-list.c',
'fu-engine.c',
'fu-engine-helper.c',
'fu-history.c',
'fu-idle.c',
'fu-install-task.c',