diff --git a/man/systemd.system-credentials.xml b/man/systemd.system-credentials.xml
index c1c8e97f0c..adc0052456 100644
--- a/man/systemd.system-credentials.xml
+++ b/man/systemd.system-credentials.xml
@@ -320,6 +320,18 @@
+
+ system.hostname
+
+ Accepts a (transient) hostname to configure during early boot. The static hostname specified
+ in /etc/hostname, if configured, takes precedence over this setting.
+ Interpreted by the service manager (PID 1). For details see
+ systemd1.
+
+
+
+
+
home.create.*
diff --git a/src/shared/hostname-setup.c b/src/shared/hostname-setup.c
index 137c29aef5..c538506eaf 100644
--- a/src/shared/hostname-setup.c
+++ b/src/shared/hostname-setup.c
@@ -7,6 +7,7 @@
#include
#include "alloc-util.h"
+#include "creds-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
@@ -71,6 +72,26 @@ int shorten_overlong(const char *s, char **ret) {
return 1;
}
+static int acquire_hostname_from_credential(char **ret) {
+ _cleanup_free_ char *cred = NULL;
+ int r;
+
+ assert(ret);
+
+ r = read_credential_with_decryption("system.hostname", (void **) &cred, /* ret_size= */ NULL);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to read system.hostname credential, ignoring: %m");
+ if (r == 0) /* not found */
+ return -ENXIO;
+
+ if (!hostname_is_valid(cred, VALID_HOSTNAME_TRAILING_DOT)) /* check that the hostname we return is valid */
+ return log_warning_errno(SYNTHETIC_ERRNO(EBADMSG), "Hostname specified in system.hostname credential is invalid, ignoring: %s", cred);
+
+ log_info("Initializing hostname from credential.");
+ *ret = TAKE_PTR(cred);
+ return 0;
+}
+
int read_etc_hostname_stream(FILE *f, char **ret) {
int r;
@@ -164,6 +185,14 @@ int hostname_setup(bool really) {
}
}
+ if (!hn) {
+ r = acquire_hostname_from_credential(&b);
+ if (r >= 0) {
+ hn = b;
+ source = HOSTNAME_TRANSIENT;
+ }
+ }
+
if (!hn) {
_cleanup_free_ char *buf = NULL;