<commit_before><?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "../version.xml">
]>
<part id="adapting-existing">
  <title>Adapting existing mainstream distributions</title>
  <chapter id="layout">
    <title>System layout</title>
    <para>
      First, OSTree encourages systems to implement <ulink
      url="http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/">UsrMove</ulink>.
      This is simply to avoid the need for more bind mounts.  By
      default OSTree's dracut hook creates a read-only bind mount over
      <filename class='directory'>/usr</filename>; you can of course
      generate individual bind-mounts for <filename
      class='directory'>/bin</filename>, all the <filename
      class='directory'>/lib</filename> variants, etc.  So it is not
      intended to be a hard requirement.
    </para>

    <para>
      Remember, because by default the system is booted into a
      <literal>chroot</literal> equivalent, there has to be some way
      to refer to the actual physical root filesystem.  Therefore,
      your operating system tree should contain an empty <filename
      class='directory'>/sysroot</filename> directory; at boot time,
      OSTree will make this a bind mount to the physical / root
      directory.  There is precedent for this name in the initramfs
      context.  You should furthermore make a toplevel symbolic link
      <filename class='directory'>/ostree</filename> which points to
      <filename class='directory'>/sysroot/ostree</filename>, so that
      the OSTree tool at runtime can consistently find the system data
      regardless of whether it's operating on a physical root or
      inside a deployment.
    </para>

    <para>
      Because OSTree only preserves <filename
      class='directory'>/var</filename> across upgrades (each
      deployment's chroot directory will be garbage collected
      eventually), you will need to choose how to handle other
      toplevel writable directories specified by the <ulink
      url="http://www.pathname.com/fhs/">Filesystem Hierarchy
      Standard</ulink>.  Your operating system may of course choose
      not to support some of these such as <filename
      class='directory'>/usr/local</filename>, but following is the
      recommended set:
      <itemizedlist>
	<listitem>
	  <para>
	   <filename class='directory'>/home</filename> to <filename class='directory'>/var/home</filename>
	  </para>
        </listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/opt</filename> to <filename class='directory'>/var/opt</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/srv</filename> to <filename class='directory'>/var/srv</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/root</filename> to <filename class='directory'>/var/roothome</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/usr/local</filename> to <filename class='directory'>/var/local</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/mnt</filename> to <filename class='directory'>/var/mnt</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/tmp</filename> to <filename class='directory'>/sysroot/tmp</filename>
	  </para>
	</listitem>
      </itemizedlist>
    </para>

    <para>
      Furthermore, since <filename class='directory'>/var</filename>
      is empty by default, your operating system will need to
      dynamically create the <emphasis>targets</emphasis> of these at
      boot.  A good way to do this is using
      <command>systemd-tmpfiles</command>, if your OS uses systemd.
      For example:
    </para>

    <programlisting>
      <![CDATA[
d /var/log/journal 0755 root root -
L /var/home - - - - ../sysroot/home
d /var/opt 0755 root root -
d /var/srv 0755 root root -
d /var/roothome 0700 root root -
d /var/usrlocal 0755 root root -
d /var/usrlocal/bin 0755 root root -
d /var/usrlocal/etc 0755 root root -
d /var/usrlocal/games 0755 root root -
d /var/usrlocal/include 0755 root root -
d /var/usrlocal/lib 0755 root root -
d /var/usrlocal/man 0755 root root -
d /var/usrlocal/sbin 0755 root root -
d /var/usrlocal/share 0755 root root -
d /var/usrlocal/src 0755 root root -
d /var/mnt 0755 root root -
d /run/media 0755 root root -
      ]]>
</programlisting>

     <para>
       Particularly note here the double indirection of <filename
       class='directory'>/home</filename>.  By default, each
       deployment will share the global toplevel <filename
       class='directory'>/home</filename> directory on the physical
       root filesystem.  It is then up to higher levels of management
       tools to keep <filename>/etc/passwd</filename> or equivalent
       synchronized between operating systems.
     </para>
     <para>
       Each deployment can easily be reconfigured to have its own home
       directory set simply by making <filename
       class='directory'>/var/home</filename> a real directory.
     </para>
  </chapter>

  <chapter id="booting">
    <title>Booting and initramfs technology</title>
    <para>
      OSTree comes with optional dracut+systemd integration code that
      parses the <literal>ostree=</literal> kernel command line
      argument in the initramfs, and then sets up the read-only bind
      mount on <filename class='directory'>/usr</filename>, a bind
      mount on the deployment's <filename
      class='directory'>/sysroot</filename> to the physical <filename
      class='directory'>/</filename>, and then finally uses
      <literal>mount(MS_MOVE)</literal> to make the deployment root appear to be the
      root filesystem before telling systemd to switch root.
    </para>

    <para>
      If you are not using dracut or systemd, using OSTree should still
      be possible, but you will have to write the integration code.  Patches
      to support other initramfs technologies and init systems, if sufficiently
      clean, will likely be accepted upstream.
    </para>

    <para>
      A further specific note regarding <command>sysvinit</command>:
      OSTree used to support recording device files such the
      <filename>/dev/initctl</filename> FIFO, but no longer does.
      It's recommended to just patch your initramfs to create this at
      boot.
    </para>
  </chapter>

  <chapter id="lib-passwd">
    <title>/lib/passwd</title>
    <para>
      In order to ship an OS that contains both system users and users
      dynamically created on client machines, you will need to choose
      a solution for <filename>/etc/passwd</filename>.  The core
      problem is that if you add a user to the system for a daemon,
      the OSTree upgrade process for <filename
      class='directory'>/etc</filename> will simply notice that
      because <filename>/etc/passwd</filename> differs from the
      previous default, it will keep the modified config file, and
      your new OS user will not be visible.
    </para>
    <para>
      The solution chosen for the <ulink
      url="https://live.gnome.org/Projects/GnomeContinuous">gnome-continuous</ulink>
      operating system is to create
      <filename>/usr/lib/passwd</filename>, and to include a NSS
      module <ulink
      url="https://github.com/aperezdc/nss-altfiles">nss-altfiles</ulink>
      which instructs glibc to read from it.  Then, the build system places
      all system users there, freeing up <filename>/etc/passwd</filename>
      to be purely a database of local users.
    </para>
  </chapter>

  <chapter id="adapting-package-manager">
    <title>Adapting existing package managers</title>
    <para>
      The largest endeavor is likely to be redesigning your
      distribution's package manager to be on top of OSTree,
      particularly if you want to keep compatibility with the "old<commit_msg>doc: adapting-existing: Update story on latest /usr/lib/passwd bits<commit_after><?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "../version.xml">
]>
<part id="adapting-existing">
  <title>Adapting existing mainstream distributions</title>
  <chapter id="layout">
    <title>System layout</title>
    <para>
      First, OSTree encourages systems to implement <ulink
      url="http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/">UsrMove</ulink>.
      This is simply to avoid the need for more bind mounts.  By
      default OSTree's dracut hook creates a read-only bind mount over
      <filename class='directory'>/usr</filename>; you can of course
      generate individual bind-mounts for <filename
      class='directory'>/bin</filename>, all the <filename
      class='directory'>/lib</filename> variants, etc.  So it is not
      intended to be a hard requirement.
    </para>

    <para>
      Remember, because by default the system is booted into a
      <literal>chroot</literal> equivalent, there has to be some way
      to refer to the actual physical root filesystem.  Therefore,
      your operating system tree should contain an empty <filename
      class='directory'>/sysroot</filename> directory; at boot time,
      OSTree will make this a bind mount to the physical / root
      directory.  There is precedent for this name in the initramfs
      context.  You should furthermore make a toplevel symbolic link
      <filename class='directory'>/ostree</filename> which points to
      <filename class='directory'>/sysroot/ostree</filename>, so that
      the OSTree tool at runtime can consistently find the system data
      regardless of whether it's operating on a physical root or
      inside a deployment.
    </para>

    <para>
      Because OSTree only preserves <filename
      class='directory'>/var</filename> across upgrades (each
      deployment's chroot directory will be garbage collected
      eventually), you will need to choose how to handle other
      toplevel writable directories specified by the <ulink
      url="http://www.pathname.com/fhs/">Filesystem Hierarchy
      Standard</ulink>.  Your operating system may of course choose
      not to support some of these such as <filename
      class='directory'>/usr/local</filename>, but following is the
      recommended set:
      <itemizedlist>
	<listitem>
	  <para>
	   <filename class='directory'>/home</filename> to <filename class='directory'>/var/home</filename>
	  </para>
        </listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/opt</filename> to <filename class='directory'>/var/opt</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/srv</filename> to <filename class='directory'>/var/srv</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/root</filename> to <filename class='directory'>/var/roothome</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/usr/local</filename> to <filename class='directory'>/var/local</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/mnt</filename> to <filename class='directory'>/var/mnt</filename>
	  </para>
	</listitem>
	<listitem>
	  <para>
	    <filename class='directory'>/tmp</filename> to <filename class='directory'>/sysroot/tmp</filename>
	  </para>
	</listitem>
      </itemizedlist>
    </para>

    <para>
      Furthermore, since <filename class='directory'>/var</filename>
      is empty by default, your operating system will need to
      dynamically create the <emphasis>targets</emphasis> of these at
      boot.  A good way to do this is using
      <command>systemd-tmpfiles</command>, if your OS uses systemd.
      For example:
    </para>

    <programlisting>
      <![CDATA[
d /var/log/journal 0755 root root -
L /var/home - - - - ../sysroot/home
d /var/opt 0755 root root -
d /var/srv 0755 root root -
d /var/roothome 0700 root root -
d /var/usrlocal 0755 root root -
d /var/usrlocal/bin 0755 root root -
d /var/usrlocal/etc 0755 root root -
d /var/usrlocal/games 0755 root root -
d /var/usrlocal/include 0755 root root -
d /var/usrlocal/lib 0755 root root -
d /var/usrlocal/man 0755 root root -
d /var/usrlocal/sbin 0755 root root -
d /var/usrlocal/share 0755 root root -
d /var/usrlocal/src 0755 root root -
d /var/mnt 0755 root root -
d /run/media 0755 root root -
      ]]>
</programlisting>

     <para>
       Particularly note here the double indirection of <filename
       class='directory'>/home</filename>.  By default, each
       deployment will share the global toplevel <filename
       class='directory'>/home</filename> directory on the physical
       root filesystem.  It is then up to higher levels of management
       tools to keep <filename>/etc/passwd</filename> or equivalent
       synchronized between operating systems.
     </para>
     <para>
       Each deployment can easily be reconfigured to have its own home
       directory set simply by making <filename
       class='directory'>/var/home</filename> a real directory.
     </para>
  </chapter>

  <chapter id="booting">
    <title>Booting and initramfs technology</title>
    <para>
      OSTree comes with optional dracut+systemd integration code that
      parses the <literal>ostree=</literal> kernel command line
      argument in the initramfs, and then sets up the read-only bind
      mount on <filename class='directory'>/usr</filename>, a bind
      mount on the deployment's <filename
      class='directory'>/sysroot</filename> to the physical <filename
      class='directory'>/</filename>, and then finally uses
      <literal>mount(MS_MOVE)</literal> to make the deployment root appear to be the
      root filesystem before telling systemd to switch root.
    </para>

    <para>
      If you are not using dracut or systemd, using OSTree should still
      be possible, but you will have to write the integration code.  Patches
      to support other initramfs technologies and init systems, if sufficiently
      clean, will likely be accepted upstream.
    </para>

    <para>
      A further specific note regarding <command>sysvinit</command>:
      OSTree used to support recording device files such the
      <filename>/dev/initctl</filename> FIFO, but no longer does.
      It's recommended to just patch your initramfs to create this at
      boot.
    </para>
  </chapter>

  <chapter id="lib-passwd">
    <title>/usr/lib/passwd</title>
    <para>
      Unlike traditional package systems, OSTree trees contain
      <emphasis>numeric</emphasis> uid and gids.  Furthermore, it does
      not have a <literal>%post</literal> type mechanism where
      <filename>useradd</filename> could be invoked.  In order to ship
      an OS that contains both system users and users dynamically
      created on client machines, you will need to choose a solution
      for <filename>/etc/passwd</filename>.  The core problem is that
      if you add a user to the system for a daemon, the OSTree upgrade
      process for <filename class='directory'>/etc</filename> will
      simply notice that because <filename>/etc/passwd</filename>
      differs from the previous default, it will keep the modified
      config file, and your new OS user will not be visible.
    </para>
    <para>
      The solution chosen for the <ulink
      url="https://live.gnome.org/Projects/GnomeContinuous">gnome-continuous</ulink>
      operating system is to create
      <filename>/usr/lib/passwd</filename>, and to include a NSS
      module <ulink
      url="https://github.com/aperezdc/nss-altfiles">nss-altfiles</ulink>
      which instructs glibc to read from it.  Then, the build system
      places all system users there, freeing up
      <filename>/etc/passwd</filename> to be purely a database of
      local users.  See also a more recent effort from <ulink
      url="http://0pointer.de/blog/projects/stateless.html">Systemd
      stateless</ulink>.
    </para>
  </chapter>

  <chapter id="adapting-package-manager">
    <title>Adapting existing package managers</title>
    <para>
      The largest endeavor is likely to be redesigning your
      distribution's package manager to be on top of OSTree,
      particularly if you want to keep compatibility with the "old
{'fraction_non_alphanumeric': 0.10272600327848946, 'fraction_numerical': 0.008803351344787809, 'mean_word_length': 3.108755300573709, 'pattern_counts': {'":': 0, '<': 349, '<?xml version=': 2, '>': 349, 'https://': 4, 'lorem ipsum': 0, 'www.': 6, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5363144', 'n_tokens_mistral': 4888, 'n_tokens_neox': 4622, 'n_words': 1703}