chiark / gitweb /
os-release: define /usr/lib/os-release as fallback for /etc/os-release
authorLennart Poettering <lennart@poettering.net>
Fri, 13 Jun 2014 17:45:52 +0000 (19:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 13 Jun 2014 18:11:59 +0000 (20:11 +0200)
The file should have been in /usr/lib/ in the first place, since it
describes the OS container in /usr (and not the configuration in /etc),
hence, let's support os-release files in /usr/lib as fallback if no
version in /etc exists, following the usual override logic.

A prior commit already enabled tmpfiles to create /etc/os-release as a
symlink to /usr/lib/os-release should it be missing, thus providing nice
compatibility with applications only checking in /etc.

While it's probably a good idea if all apps check both locations via a
fallback logic, it is only necessary in the early boot process, as long
as the /etc/os-release symlink has not been restored, in case we boot
with an empty /etc.

man/kernel-install.xml
man/os-release.xml
man/systemd-nspawn.xml
src/bootchart/bootchart.c
src/core/dbus-manager.c
src/core/main.c
src/hostname/hostnamed.c
src/journal/journal-gatewayd.c
src/kernel-install/90-loaderentry.install
src/nspawn/nspawn.c
src/shared/path-util.c

index 3612b7d..178ad1d 100644 (file)
@@ -95,14 +95,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
 
           <para>The kernel-install plugin <filename>50-depmod.install</filename> runs depmod for the <replaceable>KERNEL-VERSION</replaceable>.</para>
 
-          <para>The kernel-install plugin <filename>90-loaderentry.install</filename> copies
+          <para>The kernel-install plugin
+          <filename>90-loaderentry.install</filename> copies
           <replaceable>KERNEL-IMAGE</replaceable> to
           <filename>/boot/<replaceable>MACHINE-ID</replaceable>/<replaceable>KERNEL-VERSION</replaceable>/linux</filename>.
-          It also creates a boot loader entry according to the boot loader specification in
+          It also creates a boot loader entry according to the boot
+          loader specification in
           <filename>/boot/loader/entries/<replaceable>MACHINE-ID</replaceable>-<replaceable>KERNEL-VERSION</replaceable>.conf</filename>.
-          The title of the entry is the <replaceable>PRETTY_NAME</replaceable> parameter specified in <filename>/etc/os-release</filename>,
-          or "Linux <replaceable>KERNEL-VERSION</replaceable>", if unset.
-          If the file <filename>initrd</filename> is found next to the
+          The title of the entry is the
+          <replaceable>PRETTY_NAME</replaceable> parameter specified
+          in <filename>/etc/os-release</filename> or
+          <filename>/usr/lib/os-release</filename> (if the former is
+          missing), or "Linux
+          <replaceable>KERNEL-VERSION</replaceable>", if unset.  If
+          the file <filename>initrd</filename> is found next to the
           <filename>linux</filename> file, the initrd will be added to
           the configuration.</para>
         </listitem>
@@ -165,6 +171,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
       <varlistentry>
         <term>
           <filename>/etc/os-release</filename>
+          <filename>/usr/lib/os-release</filename>
         </term>
           <listitem>
             <para>The content of the file specifies the operating system title <replaceable>PRETTY_NAME</replaceable>.</para>
index c1dd62f..1144363 100644 (file)
 
         <refsynopsisdiv>
                 <para><filename>/etc/os-release</filename></para>
+                <para><filename>/usr/lib/os-release</filename></para>
         </refsynopsisdiv>
 
         <refsect1>
                 <title>Description</title>
 
-                <para>The <filename>/etc/os-release</filename> file
-                contains operating system identification data.</para>
+                <para>The <filename>/etc/os-release</filename> and
+                <filename>/usr/lib/os-release</filename> files contain
+                operating system identification data.</para>
 
                 <para>The basic file format of
                 <filename>os-release</filename> is a newline-separated
                 strings. Lines beginning with "#" shall be ignored as
                 comments.</para>
 
-                <para><filename>/etc/os-release</filename> contains
-                data that is defined by the operating system vendor
-                and should not be changed by the administrator.</para>
+                <para>The file <filename>/etc/os-release</filename>
+                takes precedence over
+                <filename>/usr/lib/os-release</filename>. Applications
+                should check for the former, and exclusively use its
+                data if it exists, and only fall back to
+                <filename>/usr/lib/os-release</filename> if it is
+                missing. Applications should not read data from both
+                files at the same
+                time. <filename>/usr/lib/os-release</filename> is the
+                recommended place to store OS release information as
+                part of vendor trees. Frequently
+                <filename>/etc/os-release</filename> is simply a
+                symlink to <filename>/usr/lib/os-release</filename>,
+                to provide compatibility with applications only
+                looking at <filename>/etc</filename>.</para>
+
+                <para><filename>os-release</filename> contains data
+                that is defined by the operating system vendor and
+                should generally not be changed by the
+                administrator.</para>
 
                 <para>As this file only encodes names and identifiers
                 it should not be localized.</para>
 
-                <para>The file <filename>/etc/os-release</filename> might
-                be a symlink to another file, but it is important that
+                <para>The <filename>/etc/os-release</filename> and
+                <filename>/usr/lib/os-release</filename> files might
+                be symlinks to other files, but it is important that
                 the file is available from earliest boot on, and hence
                 must be located on the root file system.</para>
 
                 <para>For a longer rationale for
-                <filename>/etc/os-release</filename> please refer to
+                <filename>os-release</filename> please refer to
                 the <ulink
                 url="http://0pointer.de/blog/projects/os-release">Announcement of <filename>/etc/os-release</filename></ulink>.</para>
         </refsect1>
                 <title>Options</title>
 
                 <para>The following OS identifications parameters may be set using
-                <filename>/etc/os-release</filename>:</para>
+                <filename>os-release</filename>:</para>
 
                 <variablelist>
 
index d668703..950558f 100644 (file)
 
                 <para>As a safety check
                 <command>systemd-nspawn</command> will verify the
-                existence of <filename>/etc/os-release</filename> in
-                the container tree before starting the container (see
+                existence of <filename>/usr/lib/os-release</filename>
+                or <filename>/etc/os-release</filename> in the
+                container tree before starting the container (see
                 <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>). It
                 might be necessary to add this file to the container
                 tree manually if the OS of the container is too old to
index 958a668..01a5bf1 100644 (file)
@@ -386,10 +386,10 @@ int main(int argc, char *argv[]) {
                 if (sysfd < 0)
                         sysfd = open("/sys", O_RDONLY|O_CLOEXEC);
 
-                if (!build)
-                        parse_env_file("/etc/os-release", NEWLINE,
-                                       "PRETTY_NAME", &build,
-                                       NULL);
+                if (!build) {
+                        if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &build, NULL) == -ENOENT)
+                                parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &build, NULL);
+                }
 
                 /* wait for /proc to become available, discarding samples */
                 if (graph_start <= 0.0)
index 333c1d4..68a68a2 100644 (file)
@@ -1191,7 +1191,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda
         /* Safety check */
         if (isempty(init)) {
                 if (! path_is_os_tree(root))
-                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
+                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root);
         } else {
                 _cleanup_free_ char *p = NULL;
 
index d5d1ee2..29f2d5a 100644 (file)
@@ -1251,9 +1251,15 @@ static int status_welcome(void) {
                            "PRETTY_NAME", &pretty_name,
                            "ANSI_COLOR", &ansi_color,
                            NULL);
+        if (r == -ENOENT) {
+                r = parse_env_file("/usr/lib/os-release", NEWLINE,
+                                   "PRETTY_NAME", &pretty_name,
+                                   "ANSI_COLOR", &ansi_color,
+                                   NULL);
+        }
 
         if (r < 0 && r != -ENOENT)
-                log_warning("Failed to read /etc/os-release: %s", strerror(-r));
+                log_warning("Failed to read os-release file: %s", strerror(-r));
 
         return status_printf(NULL, false, false,
                              "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
index a350490..241d296 100644 (file)
@@ -108,6 +108,13 @@ static int context_read_data(Context *c) {
                            "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
                            "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
                            NULL);
+        if (r == -ENOENT) {
+                r = parse_env_file("/usr/lib/os-release", NEWLINE,
+                                   "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
+                                   "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
+                                   NULL);
+        }
+
         if (r < 0 && r != -ENOENT)
                 return r;
 
index 9a88676..c682666 100644 (file)
@@ -767,7 +767,8 @@ static int request_handler_machine(
         if (r < 0)
                 return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r));
 
-        parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
+        if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL) == -ENOENT)
+                parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL);
 
         get_virtualization(&v);
 
index a6a8abc..c17b8a9 100644 (file)
@@ -32,6 +32,8 @@ fi
 
 if [[ -f /etc/os-release ]]; then
     . /etc/os-release
+elif [[ -f /usr/lib/os-release ]]; then
+    . /usr/lib/os-release
 fi
 
 if ! [[ $PRETTY_NAME ]]; then
index 29ddfbb..8270348 100644 (file)
@@ -2799,7 +2799,7 @@ int main(int argc, char *argv[]) {
 
                 if (arg_boot) {
                         if (path_is_os_tree(arg_directory) <= 0) {
-                                log_error("Directory %s doesn't look like an OS root directory (/etc/os-release is missing). Refusing.", arg_directory);
+                                log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", arg_directory);
                                 goto finish;
                         }
                 } else {
index 5863429..efe464d 100644 (file)
@@ -526,12 +526,18 @@ int path_is_os_tree(const char *path) {
         char *p;
         int r;
 
-        /* We use /etc/os-release as flag file if something is an OS */
+        /* We use /usr/lib/os-release as flag file if something is an OS */
+        p = strappenda(path, "/usr/lib/os-release");
+        r = access(p, F_OK);
+
+        if (r >= 0)
+                return 1;
 
+        /* Also check for the old location in /etc, just in case. */
         p = strappenda(path, "/etc/os-release");
         r = access(p, F_OK);
 
-        return r < 0 ? 0 : 1;
+        return r >= 0;
 }
 
 int find_binary(const char *name, char **filename) {