summaryrefslogtreecommitdiff
path: root/adapting-existing/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'adapting-existing/index.html')
-rw-r--r--adapting-existing/index.html441
1 files changed, 441 insertions, 0 deletions
diff --git a/adapting-existing/index.html b/adapting-existing/index.html
new file mode 100644
index 00000000..9bec41fa
--- /dev/null
+++ b/adapting-existing/index.html
@@ -0,0 +1,441 @@
+
+
+<!DOCTYPE html>
+
+<html lang="en-US">
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge">
+
+ <link rel="stylesheet" href="/ostree/assets/css/just-the-docs-default.css">
+
+
+
+
+ <script src="/ostree/assets/js/vendor/lunr.min.js"></script>
+
+
+
+
+ <script src="/ostree/assets/js/just-the-docs.js"></script>
+
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+
+
+
+ <!-- Begin Jekyll SEO tag v2.8.0 -->
+<title>Adapting existing mainstream distributions | ostreedev/ostree</title>
+<meta name="generator" content="Jekyll v3.9.3" />
+<meta property="og:title" content="Adapting existing mainstream distributions" />
+<meta property="og:locale" content="en_US" />
+<meta name="description" content="ostree documentation" />
+<meta property="og:description" content="ostree documentation" />
+<link rel="canonical" href="https://ostreedev.github.io/ostree/adapting-existing/" />
+<meta property="og:url" content="https://ostreedev.github.io/ostree/adapting-existing/" />
+<meta property="og:site_name" content="ostreedev/ostree" />
+<meta property="og:type" content="website" />
+<meta name="twitter:card" content="summary" />
+<meta property="twitter:title" content="Adapting existing mainstream distributions" />
+<script type="application/ld+json">
+{"@context":"https://schema.org","@type":"WebPage","description":"ostree documentation","headline":"Adapting existing mainstream distributions","url":"https://ostreedev.github.io/ostree/adapting-existing/"}</script>
+<!-- End Jekyll SEO tag -->
+
+
+
+
+</head>
+
+<body>
+ <a class="skip-to-main" href="#main-content">Skip to main content</a>
+ <svg xmlns="http://www.w3.org/2000/svg" class="d-none">
+ <symbol id="svg-link" viewBox="0 0 24 24">
+ <title>Link</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
+ </svg>
+</symbol>
+
+ <symbol id="svg-menu" viewBox="0 0 24 24">
+ <title>Menu</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
+ <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
+ </svg>
+</symbol>
+
+ <symbol id="svg-arrow-right" viewBox="0 0 24 24">
+ <title>Expand</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
+ <polyline points="9 18 15 12 9 6"></polyline>
+ </svg>
+</symbol>
+
+ <!-- Feather. MIT License: https://github.com/feathericons/feather/blob/master/LICENSE -->
+<symbol id="svg-external-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link">
+ <title id="svg-external-link-title">(external link)</title>
+ <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line>
+</symbol>
+
+
+ <symbol id="svg-doc" viewBox="0 0 24 24">
+ <title>Document</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
+ <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
+ </svg>
+</symbol>
+
+ <symbol id="svg-search" viewBox="0 0 24 24">
+ <title>Search</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
+ <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
+ </svg>
+</symbol>
+
+
+
+ <!-- Bootstrap Icons. MIT License: https://github.com/twbs/icons/blob/main/LICENSE.md -->
+<symbol id="svg-copy" viewBox="0 0 16 16">
+ <title>Copy</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
+ <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
+ <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
+ </svg>
+</symbol>
+<symbol id="svg-copied" viewBox="0 0 16 16">
+ <title>Copied</title>
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard-check-fill" viewBox="0 0 16 16">
+ <path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/>
+ <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/>
+ </svg>
+</symbol>
+
+
+</svg>
+
+ <div class="side-bar">
+ <div class="site-header">
+ <a href="/ostree/" class="site-title lh-tight">
+ ostreedev/ostree
+
+</a>
+ <a href="#" id="menu-button" class="site-button">
+ <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg>
+ </a>
+ </div>
+ <nav aria-label="Main" id="site-nav" class="site-nav">
+
+
+ <ul class="nav-list"><li class="nav-list-item"><a href="/ostree/" class="nav-list-link">libostree</a></li><li class="nav-list-item"><a href="/ostree/introduction/" class="nav-list-link">OSTree Overview</a></li><li class="nav-list-item"><a href="/ostree/repo/" class="nav-list-link">Anatomy of an OSTree repository</a></li><li class="nav-list-item"><a href="/ostree/deployment/" class="nav-list-link">Deployments</a></li><li class="nav-list-item"><a href="/ostree/atomic-upgrades/" class="nav-list-link">Atomic Upgrades</a></li><li class="nav-list-item active"><a href="/ostree/adapting-existing/" class="nav-list-link active">Adapting existing mainstream distributions</a></li><li class="nav-list-item"><a href="/ostree/formats/" class="nav-list-link">OSTree data formats</a></li><li class="nav-list-item"><a href="/ostree/buildsystem-and-repos/" class="nav-list-link">Writing a buildsystem and managing repositories</a></li><li class="nav-list-item"><a href="/ostree/repository-management/" class="nav-list-link">Managing content in OSTree repositories</a></li><li class="nav-list-item"><a href="/ostree/related-projects/" class="nav-list-link">Related Projects</a></li><li class="nav-list-item"><a href="/ostree/ima/" class="nav-list-link">Using Linux IMA with OSTree</a></li><li class="nav-list-item"><a href="/ostree/CONTRIBUTING/" class="nav-list-link">Contributing</a></li><li class="nav-list-item"><a href="/ostree/contributing-tutorial/" class="nav-list-link">OSTree Contributing Tutorial</a></li><li class="nav-list-item"><a href="/ostree/README-historical/" class="nav-list-link">Historical OSTree README</a></li></ul>
+
+ </nav>
+
+
+
+ <footer class="site-footer">
+ This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
+ </footer>
+
+</div>
+
+ <div class="main" id="top">
+ <div id="main-header" class="main-header">
+
+
+
+<div class="search">
+ <div class="search-input-wrap">
+ <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search ostreedev/ostree" aria-label="Search ostreedev/ostree" autocomplete="off">
+ <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
+ </div>
+ <div id="search-results" class="search-results"></div>
+</div>
+
+
+
+
+ <nav aria-label="Auxiliary" class="aux-nav">
+ <ul class="aux-nav-list">
+
+ <li class="aux-nav-list-item">
+ <a href="https://github.com/ostreedev/ostree" class="site-button"
+
+ >
+ OSTree on GitHub
+ </a>
+ </li>
+
+ </ul>
+</nav>
+
+
+</div>
+
+ <div id="main-content-wrap" class="main-content-wrap">
+
+
+
+
+ <div id="main-content" class="main-content" role="main">
+
+ <h1 class="no_toc" id="adapting-existing-mainstream-distributions">
+
+
+ <a href="#adapting-existing-mainstream-distributions" class="anchor-heading" aria-labelledby="adapting-existing-mainstream-distributions"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Adapting existing mainstream distributions
+
+
+</h1>
+
+
+<ol id="markdown-toc">
+ <li><a href="#system-layout" id="markdown-toc-system-layout">System layout</a></li>
+ <li><a href="#booting-and-initramfs-technology" id="markdown-toc-booting-and-initramfs-technology">Booting and initramfs technology</a></li>
+ <li><a href="#usrlibpasswd" id="markdown-toc-usrlibpasswd">/usr/lib/passwd</a></li>
+ <li><a href="#adapting-existing-package-managers" id="markdown-toc-adapting-existing-package-managers">Adapting existing package managers</a> <ol>
+ <li><a href="#licensing-for-this-document" id="markdown-toc-licensing-for-this-document">Licensing for this document:</a></li>
+ </ol>
+ </li>
+</ol>
+<h2 id="system-layout">
+
+
+ <a href="#system-layout" class="anchor-heading" aria-labelledby="system-layout"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> System layout
+
+
+</h2>
+
+
+<p>First, OSTree encourages systems to implement
+<a href="http://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/">UsrMove</a>
+This is simply to avoid the need for more bind mounts. By default
+OSTree’s dracut hook creates a read-only bind mount over <code class="language-plaintext highlighter-rouge">/usr</code>; you
+can of course generate individual bind-mounts for <code class="language-plaintext highlighter-rouge">/bin</code>, all the
+<code class="language-plaintext highlighter-rouge">/lib</code> variants, etc. So it is not intended to be a hard requirement.</p>
+
+<p>Remember, because by default the system is booted into a <code class="language-plaintext highlighter-rouge">chroot</code>
+equivalent, there has to be some way to refer to the actual physical
+root filesystem. Therefore, your operating system tree should contain
+an empty <code class="language-plaintext highlighter-rouge">/sysroot</code> 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 <code class="language-plaintext highlighter-rouge">/ostree</code> which points to <code class="language-plaintext highlighter-rouge">/sysroot/ostree</code>, 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.</p>
+
+<p>Because OSTree only preserves <code class="language-plaintext highlighter-rouge">/var</code> 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 <a href="http://www.pathname.com/fhs/">Filesystem Hierarchy Standard</a>.
+Your operating system may of course choose
+not to support some of these such as <code class="language-plaintext highlighter-rouge">/usr/local</code>, but following is the
+recommended set:</p>
+
+<ul>
+ <li><code class="language-plaintext highlighter-rouge">/home</code> → <code class="language-plaintext highlighter-rouge">/var/home</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/opt</code> → <code class="language-plaintext highlighter-rouge">/var/opt</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/srv</code> → <code class="language-plaintext highlighter-rouge">/var/srv</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/root</code> → <code class="language-plaintext highlighter-rouge">/var/roothome</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/usr/local</code> → <code class="language-plaintext highlighter-rouge">/var/usrlocal</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/mnt</code> → <code class="language-plaintext highlighter-rouge">/var/mnt</code></li>
+ <li><code class="language-plaintext highlighter-rouge">/tmp</code> → <code class="language-plaintext highlighter-rouge">/sysroot/tmp</code></li>
+</ul>
+
+<p>Furthermore, since <code class="language-plaintext highlighter-rouge">/var</code> is empty by default, your operating system
+will need to dynamically create the <em>targets</em> of these at boot. A
+good way to do this is using <code class="language-plaintext highlighter-rouge">systemd-tmpfiles</code>, if your OS uses
+systemd. For example:</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>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 -
+</code></pre></div></div>
+
+<p>Particularly note here the double indirection of <code class="language-plaintext highlighter-rouge">/home</code>. By default,
+each deployment will share the global toplevel <code class="language-plaintext highlighter-rouge">/home</code> directory on
+the physical root filesystem. It is then up to higher levels of
+management tools to keep <code class="language-plaintext highlighter-rouge">/etc/passwd</code> or equivalent synchronized
+between operating systems. Each deployment can easily be reconfigured
+to have its own home directory set simply by making <code class="language-plaintext highlighter-rouge">/var/home</code> a real
+directory.</p>
+<h2 id="booting-and-initramfs-technology">
+
+
+ <a href="#booting-and-initramfs-technology" class="anchor-heading" aria-labelledby="booting-and-initramfs-technology"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Booting and initramfs technology
+
+
+</h2>
+
+
+<p>OSTree comes with optional dracut+systemd integration code which follows
+this logic:</p>
+
+<ul>
+ <li>Parse the <code class="language-plaintext highlighter-rouge">ostree=</code> kernel command line argument in the initramfs</li>
+ <li>Set up a read-only bind mount on <code class="language-plaintext highlighter-rouge">/usr</code></li>
+ <li>Bind mount the deployment’s <code class="language-plaintext highlighter-rouge">/sysroot</code> to the physical <code class="language-plaintext highlighter-rouge">/</code></li>
+ <li>Use <code class="language-plaintext highlighter-rouge">mount(MS_MOVE)</code> to make the deployment root appear to be the root filesystem</li>
+</ul>
+
+<p>After these steps, systemd switches root.</p>
+
+<p>If you are not using dracut or systemd, using OSTree should still be
+possible, but you will have to write the integration code. See the
+existing sources in
+<a href="https://github.com/ostreedev/ostree/tree/main/src/switchroot">src/switchroot</a>
+as a reference.</p>
+
+<p>Patches to support other initramfs technologies and init systems, if
+sufficiently clean, will likely be accepted upstream.</p>
+
+<p>A further specific note regarding <code class="language-plaintext highlighter-rouge">sysvinit</code>: OSTree used to support
+recording device files such as the <code class="language-plaintext highlighter-rouge">/dev/initctl</code> FIFO, but no longer
+does. It’s recommended to just patch your initramfs to create this at
+boot.</p>
+<h2 id="usrlibpasswd">
+
+
+ <a href="#usrlibpasswd" class="anchor-heading" aria-labelledby="usrlibpasswd"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> /usr/lib/passwd
+
+
+</h2>
+
+
+<p>Unlike traditional package systems, OSTree trees contain <em>numeric</em> uid
+and gids. Furthermore, it does not have a <code class="language-plaintext highlighter-rouge">%post</code> type mechanism
+where <code class="language-plaintext highlighter-rouge">useradd</code> 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 <code class="language-plaintext highlighter-rouge">/etc/passwd</code>. The
+core problem is that if you add a user to the system for a daemon, the
+OSTree upgrade process for <code class="language-plaintext highlighter-rouge">/etc</code> will simply notice that because
+<code class="language-plaintext highlighter-rouge">/etc/passwd</code> differs from the previous default, it will keep the
+modified config file, and your new OS user will not be visible. The
+solution chosen for the <a href="https://live.gnome.org/Projects/GnomeContinuous">Gnome Continuous</a> operating
+system is to create <code class="language-plaintext highlighter-rouge">/usr/lib/passwd</code>, and to include a NSS module
+<a href="https://github.com/aperezdc/nss-altfiles">nss-altfiles</a> which
+instructs glibc to read from it. Then, the build system places all
+system users there, freeing up <code class="language-plaintext highlighter-rouge">/etc/passwd</code> to be purely a database
+of local users. See also a more recent effort from <a href="http://0pointer.de/blog/projects/stateless.html">Systemd Stateless</a></p>
+<h2 id="adapting-existing-package-managers">
+
+
+ <a href="#adapting-existing-package-managers" class="anchor-heading" aria-labelledby="adapting-existing-package-managers"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Adapting existing package managers
+
+
+</h2>
+
+
+<p>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 way” of installing into the physical
+<code class="language-plaintext highlighter-rouge">/</code>. This section will use examples from both <code class="language-plaintext highlighter-rouge">dpkg</code> and <code class="language-plaintext highlighter-rouge">rpm</code> as the
+author has familiarity with both; but the abstract concepts should
+apply to most traditional package managers.</p>
+
+<p>There are many levels of possible integration; initially, we will
+describe the most naive implementation which is the simplest but also
+the least efficient. We will assume here that the admin is booted
+into an OSTree-enabled system, and wants to add a set of packages.</p>
+
+<p>Many package managers store their state in <code class="language-plaintext highlighter-rouge">/var</code>; but since in the
+OSTree model that directory is shared between independent versions,
+the package database must first be found in the per-deployment <code class="language-plaintext highlighter-rouge">/usr</code>
+directory. It becomes read-only; remember, all upgrades involve
+constructing a new filesystem tree, so your package manager will also
+need to create a copy of its database. Most likely, if you want to
+continue supporting non-OSTree deployments, simply have your package
+manager fall back to the legacy <code class="language-plaintext highlighter-rouge">/var</code> location if the one in <code class="language-plaintext highlighter-rouge">/usr</code>
+is not found.</p>
+
+<p>To install a set of new packages (without removing any existing ones),
+enumerate the set of packages in the currently booted deployment, and
+perform dependency resolution to compute the complete set of new
+packages. Download and unpack these new packages to a temporary
+directory.</p>
+
+<p>Now, because we are merely installing new packages and not
+removing anything, we can make the major optimization of reusing
+our existing filesystem tree, and merely
+<em>layering</em> the composed filesystem tree of
+these new packages on top. A command like this:</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ostree commit -b osname/releasename/description
+--tree=ref=$osname/$releasename/$description
+--tree=dir=/var/tmp/newpackages.13A8D0/
+</code></pre></div></div>
+
+<p>will create a new commit in the <code class="language-plaintext highlighter-rouge">$osname/$releasename/$description</code>
+branch. The OSTree SHA256 checksum of all the files in
+<code class="language-plaintext highlighter-rouge">/var/tmp/newpackages.13A8D0/</code> will be computed, but we will not
+re-checksum the present existing tree. In this layering model,
+earlier directories will take precedence, but files in later layers
+will silently override earlier layers.</p>
+
+<p>Then to actually deploy this tree for the next boot:
+<code class="language-plaintext highlighter-rouge">ostree admin deploy $osname/$releasename/$description</code></p>
+
+<p>This is essentially what <a href="https://github.com/projectatomic/rpm-ostree/">rpm-ostree</a>
+does to support its <a href="https://rpm-ostree.readthedocs.io/en/latest/manual/administrator-handbook/#hybrid-imagepackaging-via-package-layering">package layering model</a>.</p>
+<h6 id="licensing-for-this-document">
+
+
+ <a href="#licensing-for-this-document" class="anchor-heading" aria-labelledby="licensing-for-this-document"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Licensing for this document:
+
+
+</h6>
+
+<p><code class="language-plaintext highlighter-rouge">SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later)</code></p>
+
+
+
+
+
+
+
+ <hr>
+ <footer>
+
+
+ <p class="text-small text-grey-dk-100 mb-0">Copyright &copy; <a href="https://www.redhat.com">Red Hat, Inc.</a> and <a href="https://github.com/ostreedev">others</a>.</p>
+
+
+ <div class="d-flex mt-2">
+
+
+ <p class="text-small text-grey-dk-000 mb-0">
+ <a href="https://github.com/ostreedev/ostree/tree/main/docs/adapting-existing.md" id="edit-this-page">Edit this page on GitHub</a>
+ </p>
+
+ </div>
+
+ </footer>
+
+
+
+ </div>
+ </div>
+
+
+
+<div class="search-overlay"></div>
+
+
+ </div>
+
+
+</body>
+</html>
+