From 5ca428efe6e40c9d7f00c30bfbfb43935d208f6d Mon Sep 17 00:00:00 2001 From: jmarrero Date: Tue, 19 Mar 2024 14:52:09 +0000 Subject: [PATCH] jekyll build from Action b96b4ff46aa41cc99798ae0a72470164ac423d4e --- .nojekyll | 0 CONTRIBUTING/index.html | 462 + README-historical/index.html | 781 ++ adapting-existing/index.html | 472 + assets/css/just-the-docs-dark.css | 1 + assets/css/just-the-docs-default.css | 1 + assets/css/just-the-docs-light.css | 1 + assets/images/just-the-docs.png | Bin 0 -> 20992 bytes assets/images/large-image.jpg | Bin 0 -> 545267 bytes assets/images/search.svg | 1 + assets/images/small-image.jpg | Bin 0 -> 44128 bytes assets/js/just-the-docs.js | 497 + assets/js/search-data.json | 989 ++ assets/js/vendor/lunr.min.js | 61 + atomic-rollbacks/index.html | 419 + atomic-upgrades/index.html | 417 + authenticated-repos/index.html | 270 + bootloaders/index.html | 332 + buildsystem-and-repos/index.html | 450 + composefs/index.html | 420 + contributing-tutorial/index.html | 850 ++ deployment/index.html | 387 + formats/index.html | 508 + ima/index.html | 397 + index.html | 498 + introduction/index.html | 441 + man/index.html | 1 + man/ostree-admin-cleanup.html | 3 + man/ostree-admin-config-diff.html | 8 + man/ostree-admin-deploy.html | 42 + man/ostree-admin-init-fs.html | 5 + man/ostree-admin-instutil.html | 10 + man/ostree-admin-lock-finalization.html | 14 + man/ostree-admin-os-init.html | 3 + man/ostree-admin-pin.html | 9 + man/ostree-admin-post-copy.html | 7 + man/ostree-admin-set-default.html | 16 + man/ostree-admin-set-origin.html | 12 + man/ostree-admin-stateroot-init.html | 9 + man/ostree-admin-status.html | 25 + man/ostree-admin-switch.html | 5 + man/ostree-admin-undeploy.html | 15 + man/ostree-admin-unlock.html | 16 + man/ostree-admin-upgrade.html | 25 + man/ostree-admin.html | 9 + man/ostree-cat.html | 5 + man/ostree-checkout.html | 50 + man/ostree-checksum.html | 7 + man/ostree-commit.html | 89 + man/ostree-config.html | 14 + man/ostree-create-usb.html | 35 + man/ostree-diff.html | 17 + man/ostree-export.html | 5 + man/ostree-find-remotes.html | 47 + man/ostree-fsck.html | 25 + man/ostree-gpg-sign.html | 10 + man/ostree-init.html | 33 + man/ostree-log.html | 13 + man/ostree-ls.html | 17 + man/ostree-prepare-root.html | 63 + man/ostree-prune.html | 31 + man/ostree-pull-local.html | 15 + man/ostree-pull.html | 63 + man/ostree-refs.html | 36 + man/ostree-remote.html | 60 + man/ostree-reset.html | 15 + man/ostree-rev-parse.html | 7 + man/ostree-show.html | 27 + man/ostree-sign.html | 35 + man/ostree-state-overlay@.service.html | 35 + man/ostree-static-delta.html | 68 + man/ostree-summary.html | 52 + man/ostree.html | 194 + man/ostree.repo-config.html | 219 + man/ostree.repo.html | 30 + man/rofiles-fuse.html | 31 + reference/home.png | Bin 0 -> 256 bytes reference/index.html | 97 + reference/left-insensitive.png | Bin 0 -> 395 bytes reference/left.png | Bin 0 -> 262 bytes ...Core-repository-independent-functions.html | 3058 +++++ ...ee-GPG-signature-verification-results.html | 757 ++ ...-In-memory-modifiable-filesystem-tree.html | 685 + reference/ostree-OstreeRepo.html | 10655 ++++++++++++++++ ...on-system-for-asynchronous-operations.html | 623 + .../ostree-Root-partition-mount-point.html | 2586 ++++ .../ostree-SELinux-policy-management.html | 566 + reference/ostree-Signature-management.html | 878 ++ reference/ostree-Simple-upgrade-class.html | 726 ++ .../ostree-ostree-bootconfig-parser.html | 400 + .../ostree-ostree-chain-input-stream.html | 89 + .../ostree-ostree-checksum-input-stream.html | 90 + reference/ostree-ostree-content-writer.html | 101 + reference/ostree-ostree-deployment.html | 884 ++ reference/ostree-ostree-diff.html | 369 + reference/ostree-ostree-kernel-args.html | 1005 ++ reference/ostree-ostree-ref.html | 373 + reference/ostree-ostree-remote.html | 230 + reference/ostree-ostree-repo-file.html | 512 + reference/ostree-ostree-repo-finder.html | 577 + .../ostree-ostree-repo-remote-finder.html | 516 + reference/ostree-ostree-version.html | 163 + reference/ostree.devhelp2 | 679 + reference/reference.html | 2226 ++++ reference/right-insensitive.png | Bin 0 -> 373 bytes reference/right.png | Bin 0 -> 261 bytes reference/style.css | 530 + reference/up-insensitive.png | Bin 0 -> 374 bytes reference/up.png | Bin 0 -> 260 bytes related-projects/index.html | 770 ++ repo/index.html | 478 + repository-management/index.html | 533 + var/index.html | 383 + 113 files changed, 41776 insertions(+) create mode 100644 .nojekyll create mode 100644 CONTRIBUTING/index.html create mode 100644 README-historical/index.html create mode 100644 adapting-existing/index.html create mode 100644 assets/css/just-the-docs-dark.css create mode 100644 assets/css/just-the-docs-default.css create mode 100644 assets/css/just-the-docs-light.css create mode 100644 assets/images/just-the-docs.png create mode 100644 assets/images/large-image.jpg create mode 100644 assets/images/search.svg create mode 100644 assets/images/small-image.jpg create mode 100644 assets/js/just-the-docs.js create mode 100644 assets/js/search-data.json create mode 100644 assets/js/vendor/lunr.min.js create mode 100644 atomic-rollbacks/index.html create mode 100644 atomic-upgrades/index.html create mode 100644 authenticated-repos/index.html create mode 100644 bootloaders/index.html create mode 100644 buildsystem-and-repos/index.html create mode 100644 composefs/index.html create mode 100644 contributing-tutorial/index.html create mode 100644 deployment/index.html create mode 100644 formats/index.html create mode 100644 ima/index.html create mode 100644 index.html create mode 100644 introduction/index.html create mode 100644 man/index.html create mode 100644 man/ostree-admin-cleanup.html create mode 100644 man/ostree-admin-config-diff.html create mode 100644 man/ostree-admin-deploy.html create mode 100644 man/ostree-admin-init-fs.html create mode 100644 man/ostree-admin-instutil.html create mode 100644 man/ostree-admin-lock-finalization.html create mode 100644 man/ostree-admin-os-init.html create mode 100644 man/ostree-admin-pin.html create mode 100644 man/ostree-admin-post-copy.html create mode 100644 man/ostree-admin-set-default.html create mode 100644 man/ostree-admin-set-origin.html create mode 100644 man/ostree-admin-stateroot-init.html create mode 100644 man/ostree-admin-status.html create mode 100644 man/ostree-admin-switch.html create mode 100644 man/ostree-admin-undeploy.html create mode 100644 man/ostree-admin-unlock.html create mode 100644 man/ostree-admin-upgrade.html create mode 100644 man/ostree-admin.html create mode 100644 man/ostree-cat.html create mode 100644 man/ostree-checkout.html create mode 100644 man/ostree-checksum.html create mode 100644 man/ostree-commit.html create mode 100644 man/ostree-config.html create mode 100644 man/ostree-create-usb.html create mode 100644 man/ostree-diff.html create mode 100644 man/ostree-export.html create mode 100644 man/ostree-find-remotes.html create mode 100644 man/ostree-fsck.html create mode 100644 man/ostree-gpg-sign.html create mode 100644 man/ostree-init.html create mode 100644 man/ostree-log.html create mode 100644 man/ostree-ls.html create mode 100644 man/ostree-prepare-root.html create mode 100644 man/ostree-prune.html create mode 100644 man/ostree-pull-local.html create mode 100644 man/ostree-pull.html create mode 100644 man/ostree-refs.html create mode 100644 man/ostree-remote.html create mode 100644 man/ostree-reset.html create mode 100644 man/ostree-rev-parse.html create mode 100644 man/ostree-show.html create mode 100644 man/ostree-sign.html create mode 100644 man/ostree-state-overlay@.service.html create mode 100644 man/ostree-static-delta.html create mode 100644 man/ostree-summary.html create mode 100644 man/ostree.html create mode 100644 man/ostree.repo-config.html create mode 100644 man/ostree.repo.html create mode 100644 man/rofiles-fuse.html create mode 100644 reference/home.png create mode 100644 reference/index.html create mode 100644 reference/left-insensitive.png create mode 100644 reference/left.png create mode 100644 reference/ostree-Core-repository-independent-functions.html create mode 100644 reference/ostree-GPG-signature-verification-results.html create mode 100644 reference/ostree-In-memory-modifiable-filesystem-tree.html create mode 100644 reference/ostree-OstreeRepo.html create mode 100644 reference/ostree-Progress-notification-system-for-asynchronous-operations.html create mode 100644 reference/ostree-Root-partition-mount-point.html create mode 100644 reference/ostree-SELinux-policy-management.html create mode 100644 reference/ostree-Signature-management.html create mode 100644 reference/ostree-Simple-upgrade-class.html create mode 100644 reference/ostree-ostree-bootconfig-parser.html create mode 100644 reference/ostree-ostree-chain-input-stream.html create mode 100644 reference/ostree-ostree-checksum-input-stream.html create mode 100644 reference/ostree-ostree-content-writer.html create mode 100644 reference/ostree-ostree-deployment.html create mode 100644 reference/ostree-ostree-diff.html create mode 100644 reference/ostree-ostree-kernel-args.html create mode 100644 reference/ostree-ostree-ref.html create mode 100644 reference/ostree-ostree-remote.html create mode 100644 reference/ostree-ostree-repo-file.html create mode 100644 reference/ostree-ostree-repo-finder.html create mode 100644 reference/ostree-ostree-repo-remote-finder.html create mode 100644 reference/ostree-ostree-version.html create mode 100644 reference/ostree.devhelp2 create mode 100644 reference/reference.html create mode 100644 reference/right-insensitive.png create mode 100644 reference/right.png create mode 100644 reference/style.css create mode 100644 reference/up-insensitive.png create mode 100644 reference/up.png create mode 100644 related-projects/index.html create mode 100644 repo/index.html create mode 100644 repository-management/index.html create mode 100644 var/index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/CONTRIBUTING/index.html b/CONTRIBUTING/index.html new file mode 100644 index 0000000000..83a6678fe7 --- /dev/null +++ b/CONTRIBUTING/index.html @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Contributing | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
+
+ + + + + + + + + + + +
+ +
+ + + + +
+ +

+ + + Contributing + + +

+ + +
    +
  1. Submitting patches
  2. +
  3. Commit message style
  4. +
  5. Running the test suite
  6. +
  7. Coding style
  8. +
  9. Contributing Tutorial
  10. +
  11. Release process
  12. +
+ + +

+ + + Submitting patches + + +

+ + +

A majority of current maintainers prefer the GitHub pull request +model, and this motivated moving the primary git repository to +https://github.com/ostreedev/ostree.

+ +

However, we do not use the “Merge pull request” button, because we do +not like merge commits for one-patch pull requests, among other +reasons. See this issue +for more information. Instead, we use an instance of +Homu, currently known as +cgwalters-bot.

+ +

As a review proceeds, the preferred method is to push fixup! commits. Any commits committed with the --fixup option will have have the word fixup! in its commit title. This is to indicate that this particular commit will be squashed with the commit that was specified in this command, git commit --fixup <commit ref or hash>. Homu knows how to use --autosquash when performing the final merge.

+ +

See the +Git documentation for more +information.

+ +

Alternative methods if you don’t like GitHub (also fully supported):

+ +
    +
  1. Send mail to ostree-list@gnome.org, with the patch attached
  2. +
  3. Attach them to https://bugzilla.gnome.org/
  4. +
+ +

It is likely however once a patch is ready to apply a maintainer +will push it to a GitHub PR, and merge via Homu.

+

+ + + Commit message style + + +

+ + +

Please look at git log and match the commit log style, which is very +similar to the +Linux kernel.

+ +

You may use Signed-off-by, but we’re not requiring it.

+ +

General Commit Message Guidelines:

+ +
    +
  1. Title +
      +
    • Specify the context or category of the changes e.g. lib for library changes, docs for document changes, bin/<command-name> for command changes, etc.
    • +
    • Begin the title with the first letter of the first word capitalized.
    • +
    • Aim for less than 50 characters, otherwise 72 characters max.
    • +
    • Do not end the title with a period.
    • +
    • Use an imperative tone.
    • +
    +
  2. +
  3. Body +
      +
    • Separate the body with a blank line after the title.
    • +
    • Begin a paragraph with the first letter of the first word capitalized.
    • +
    • Each paragraph should be formatted within 72 characters.
    • +
    • Content should be about what was changed and why this change was made.
    • +
    • If your commit fixes an issue, the commit message should end with Closes: #<number>.
    • +
    +
  4. +
+ +

Commit Message example:

+ +
<context>: Less than 50 characters for subject title
+
+A paragraph of the body should be within 72 characters.
+
+This paragraph is also less than 72 characters.
+
+ +

For more information see How to Write a Git Commit Message

+ +

Editing a Committed Message:

+ +

To edit the message from the most recent commit run git commit --amend. To change older commits on the branch use git rebase -i. For a successful rebase have the branch track upstream main. Once the changes have been made and saved, run git push --force origin <branch-name>.

+

+ + + Running the test suite + + +

+ + +

OSTree uses both make check and supports the +Installed Tests +model as well (if --enable-installed-tests is provided).

+

+ + + Coding style + + +

+ + +

Indentation is GNU. Files should start with the appropriate mode lines.

+ +

Use GCC __attribute__((cleanup)) wherever possible. If interacting +with a third party library, try defining local cleanup macros.

+ +

Use GError and GCancellable where appropriate.

+ +

Prefer returning gboolean to signal success/failure, and have output +values as parameters.

+ +

Prefer linear control flow inside functions (aside from standard +loops). In other words, avoid “early exits” or use of goto besides +goto out;.

+ +

This is an example of an “early exit”:

+ +
static gboolean
+myfunc (...)
+{
+    gboolean ret = FALSE;
+
+    /* some code */
+
+    /* some more code */
+
+    if (condition)
+      return FALSE;
+
+    /* some more code */
+
+    ret = TRUE;
+  out:
+    return ret;
+}
+
+ +

If you must shortcut, use:

+ +
if (condition)
+  {
+    ret = TRUE;
+    goto out;
+  }
+
+ +

A consequence of this restriction is that you are encouraged to avoid +deep nesting of loops or conditionals. Create internal static helper +functions, particularly inside loops. For example, rather than:

+ +
while (condition)
+  {
+    /* some code */
+    if (condition)
+      {
+         for (i = 0; i < somevalue; i++)
+           {
+              if (condition)
+                {
+                  /* deeply nested code */
+                }
+
+                /* more nested code */
+           }
+      }
+  }
+
+ +

Instead do this:

+ +
static gboolean
+helperfunc (..., GError **error)
+{
+  if (condition)
+   {
+     /* deeply nested code */
+   }
+
+  /* more nested code */
+
+  return ret;
+}
+
+while (condition)
+  {
+    /* some code */
+    if (!condition)
+      continue;
+
+    for (i = 0; i < somevalue; i++)
+      {
+        if (!helperfunc (..., i, error))
+          goto out;
+      }
+  }
+
+

+ + + Contributing Tutorial + + +

+ + +

For a detailed walk-through on building, modifying, and testing, see this tutorial on how to start contributing to OSTree.

+

+ + + Release process + + +

+ + +

Releases can be performed by creating a new release ticket and following the steps in the checklist there.

+ + + + + + + +
+ + + + +
+
+ + + +
+ + +
+ + + + + diff --git a/README-historical/index.html b/README-historical/index.html new file mode 100644 index 0000000000..6337e9ad35 --- /dev/null +++ b/README-historical/index.html @@ -0,0 +1,781 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Historical OSTree README | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
+
+ + + + + + + + + + + +
+ +
+ + + + +
+ +

+ + + Historical OSTree README + + +

+ + + + +

This file is outdated, but some of the text here is still useful for +historical context. I’m preserving it (explicitly still in the tree) +for posterity.

+

+ + + Problem statement + + +

+ + +

Hacking on the core operating system is painful - this includes most +of GNOME from upower and NetworkManager up to gnome-shell. I want a +system that matches these requirements:

+ +
    +
  1. Does not disturb your existing OS
  2. +
  3. Is not terribly slow to use
  4. +
  5. Shares your $HOME - you have your data
  6. +
  7. Allows easy rollback
  8. +
  9. Ideally allows access to existing apps
  10. +
+

+ + + Comparison with existing tools + + +

+ + +
    +
  • +

    Virtualization

    + +

    Fails on points 2) and 3). Actually qemu-kvm can be pretty fast, + but in a lot of cases there is no substitute for actually booting + on bare metal; GNOME 3 really needs some hardware GPU + acceleration.

    +
  • +
  • +

    Rebuilding distribution packages

    + +

    Fails on points 1) and 4). Is also just very annoying: dpkg/rpm + both want tarballs, which you don’t have since you’re working from + git. The suggested “mock/pbuilder” type chroot builds are slow. + And even with non-chroot builds there is lots of pointless build + wrapping going on. Both dpkg and rpm also are poor at helping you + revert back to the original system.

    + +

    All of this can be scripted to be less bad of course - and I have + worked on such scripts. But fundamentally you’re still fighting + the system, and if you’re hacking on a lowlevel library like say + glib, you can easily get yourself to the point where you need a + recovery CD - at that point your edit/compile/debug cycle is just + too long.

    +
  • +
  • +

    “sudo make install”

    + +

    Now your system is in an undefined state. You can use e.g. rpm + -qV to try to find out what you overwrote, but neither dpkg nor + rpm will help clean up any files left over that aren’t shipped by + the old package.

    + +

    This is most realistic option for people hacking on system + components currently, but ostree will be better.

    +
  • +
  • +

    LXC / containers

    + +

    Fails on 3), and 4) is questionable. Also shares the annoying part +of rebuilding distribution packages. LXC is focused on running +multiple server systems at the same time, which isn’t what we +want (at least, not right now), and honestly even trying to support +that for a graphical desktop would be a lot of tricky work, for +example getting two GDM instances not to fight over VT +allocations. But some bits of the technology may make sense to use.

    +
  • +
  • +

    jhbuild + distribution packages

    + +

    The state of the art in GNOME - but can only build non-root things - + this means you can’t build NetworkManager, and thus are permanently + stuck on whatever the distro provides.

    +
  • +
+

+ + + Who is ostree for? + + +

+ + +

First - operating system developers and testers. I specifically keep +a few people in mind - Dan Williams and Eric Anholt, as well as myself +obviously. For Eric Anholt, a key use case for him is being able to +try out the latest gnome-shell, and combine it with his work on Mesa, +and see how it works/performs - while retaining the ability to roll +back if one or both breaks.

+ +

The rollback concept is absolutely key for shipping anything to +enthusiasts or knowledable testers. With a system like this, a tester +can easily perform a local rollback - something just not well +supported by dpkg/rpm. (What about Conary? See below.)

+ +

Also, distributing operating system trees (instead of packages) gives +us a sane place to perform automated QA before we ship it to +testers. We should never be wasting these people’s time.

+ +

Even better, this system would allow testers to bisect across +operating system builds, and do so very efficiently.

+

+ + + The core idea - chroots + + +

+ + +

chroots are the original lightweight “virtualization”. Let’s use +them. So basically, you install a mainstream distribution (say +Debian). It has a root filesystem like this:

+ +
	/usr
+	/etc
+	/home
+	...
+
+ +

Now, what we can do is have a system that installs chroots as a subdirectory +of the root, like:

+ +
	/ostree/gnomeos-3.0-opt-393a4555/{usr,etc,sbin,...}
+	/ostree/gnomeos-3.2-opt-7e9788a2/{usr,etc,sbin,...}
+
+ +

These live in the same root filesystem as your regular distribution +(Note though, the root partition should be reasonably sized, or +hopefully you’ve used just one big partition).

+ +

You should be able to boot into one of these roots. Since ostree +lives inside a distro created partition, a tricky part here is that we +need to know how to interact with the installed distribution’s grub. +This is an annoying but tractable problem.

+ +

First, we install a kernel+initramfs alongside the distribution’s. +Then, we have a “trampoline” ostree-init binary which is statically +linked, and boot the kernel with init=/ostree/ostree-init. This then +takes care of chrooting and running the init binary.

+ +

An important note here is that we bind mount the real /home. This +means you have your data. This also implies we share uid/gid, so +/etc/passwd will have to be in sync. Probably what we’ll do is have a +script to pull the data from the “host” OS.

+ +

I’ve decided for now to move /var into /ostree to avoid sharing it +with the “host” distribution, because in practice we’re likely +to hit incompatibilities.

+ +

Do note however /etc lives inside the OSTree; it’s presently +versioned and readonly like everything else.

+ +

On a pure OSTree system, the filesystem layout will look like this:

+ +
	.
+	|-- boot
+	|-- home
+	|-- ostree
+	|   |-- var
+	|   |-- current -> gnomeos-3.2-opt-7e9788a2
+	|   |-- gnomeos-3.0-opt-393a4555
+	|   |   |-- etc
+	|   |   |-- lib
+	|   |   |-- mnt
+	|   |   |-- proc
+	|   |   |-- run
+	|   |   |-- sbin
+	|   |   |-- srv
+	|   |   |-- sys
+	|   |   `-- usr
+	|   `-- gnomeos-3.2-opt-7e9788a2
+	|       |-- etc
+	|       |-- lib
+	|       |-- mnt
+	|       |-- proc
+	|       |-- run
+	|       |-- sbin
+	|       |-- srv
+	|       |-- sys
+	|       `-- usr
+	|-- root
+
+

+ + + Making this efficient + + +

+ + +

One of the first things you’ll probably ask is “but won’t that use a +lot of disk space”? Indeed, it will, if you just unpack a set of RPMs +or .debs into each root.

+ +

Besides chroots, there’s another old Unix idea we can take advantage +of - hard links. These allow sharing the underlying data of a file, +with the tradeoff that changing any one file will change all names +that point to it. This mutability means that we have to either:

+ +
    +
  1. Make sure everything touching the operating system breaks hard links +This is probably tractable over a long period of time, but if anything +has a bug, then it corrupts the file effectively.
  2. +
  3. Make the core OS read-only, with a well-defined mechanism for mutating +under the control of ostree.
  4. +
+ +

I chose 2.

+

+ + + A userspace content-addressed versioning filesystem + + +

+ + +

At its very core, that’s what ostree is. Just like git. If you +understand git, you know it’s not like other revision control systems. +git is effectively a specialized, userspace filesystem, and that is a +very powerful idea.

+ +

At the core of git is the idea of “content-addressed objects”. For +background on this, see http://book.git-scm.com/7_how_git_stores_objects.html

+ +

Why not just use git? Basically because git is designed mainly for +source trees - it goes to effort to be sure it’s compressing text for +example, under the assumption that you have a lot of text. Its +handling of binaries is very generic and unoptimized.

+ +

In contrast, ostree is explicitly designed for binaries, and in +particular one type of binary - ELF executables (or it will be once we +start using bsdiff).

+ +

Another big difference versus git is that ostree uses hard links +between “checkouts” and the repository. This means each checkout uses +almost no additional space, and is extremely fast to check out. We +can do this because again each checkout is designed to be read-only.

+ +

So we mentioned above there are:

+ +
	/ostree/gnomeos-3.2-opt-7e9788a2
+	/ostree/gnomeos-3.2-opt-393a4555
+
+ +

There is also a “repository” that looks like this:

+ +
	/ostree/repo/objects/17/a95e8ca0ba655b09cb68d7288342588e867ee0.file
+	/ostree/repo/objects/17/68625e7ff5a8db77904c77489dc6f07d4afdba.meta
+	/ostree/repo/objects/17/cc01589dd8540d85c0f93f52b708500dbaa5a9.file
+	/ostree/repo/objects/30
+	/ostree/repo/objects/30/6359b3ca7684358a3988afd005013f13c0c533.meta
+	/ostree/repo/objects/30/8f3c03010cedd930b1db756ce659c064f0cd7f.meta
+	/ostree/repo/objects/30/8cf0fd8e63dfff6a5f00ba5a48f3b92fb52de7.file
+	/ostree/repo/objects/30/6cad7f027d69a46bb376044434bbf28d63e88d.file
+
+ +

Each object is either metadata (like a commit or tree), or a hard link +to a regular file.

+ +

Note that also unlike git, the checksum here includes metadata such +as uid, gid, permissions, and extended attributes. (It does not include +file access times, since those shouldn’t matter for the OS)

+ +

This is another important component to allowing the hardlinks. We +wouldn’t want say all empty files to be shared necessarily. (Though +maybe this is wrong, and since the OS is readonly, we can make all +files owned by root without loss of generality).

+ +

However this tradeoff means that we probably need a second index by +content, so we don’t have to redownload the entire OS if permissions +change =)

+

+ + + Atomic upgrades, rollback + + +

+ + +

OSTree is designed to atomically swap operating systems - such that +during an upgrade and reboot process, you either get the full new +system, or the old one. There is no “Please don’t turn off your +computer”. We do this by simply using a symbolic link like:

+ +

/ostree/current -> /ostree/gnomeos-3.4-opt-e3b0c4429

+ +

Where gnomeos-e3b0c4429 has the full regular filesystem tree with usr/ +etc/ directories as above. To upgrade or rollback (there is no +difference internally), we simply check out a new tree into +gnomeos-b90ae4763 for example, then swap the “current” symbolic link, +then remove the old tree.

+ +

But does this mean you have to reboot for OS upgrades? Very likely, +yes - and this is no different from RPM/deb or whatever. They just +typically lie to you about it =)

+ +

A typical model with RPM/deb is to unpack the new files, then use some +IPC mechanism (SIGHUP, a control binary like /usr/sbin/apachectl) to +signal the running process to reload. There are multiple problems +with this - one is that in the new state, daemon A may depend on the +updated configuration in daemon B. This may not be particularly +common in default configurations, but it’s highly likely that that +some deployments will have e.g. apache talking to a local MySQL +instance. So you really want to do is only apply the updated +configuration when all the files are in place; not after each RPM or +.deb is installed.

+ +

What’s even harder is the massive set of race conditions that are +possible while RPM/deb are in the process of upgrading. Cron jobs are +very likely to hit this. If we want the ability to apply updates to a +live system, we could first pause execution of non-upgrade userspace +tasks. This could be done via SIGSTOP for example. Then, we can swap +around the filesystem tree, and then finally attempt to apply updates +via SIGHUP, and if possible, restart processes.

+

+ + + Configuration Management + + +

+ + +

By now if you’ve thought about this problem domain before, you’re wondering +about configuration management. In other words, if the OS is read only, +how do I edit /etc/sudoers?

+ +

Well, have you ever been a system administrator on a zypper/yum +system, done an RPM update, which then drops .rpmnew files in your +/etc/ that you have to go and hunt for with “find” or something, and +said to yourself, “Wow, this system is awesome!!!” ? Right, that’s +what I thought.

+ +

Configuration (and systems) management is a tricky problem, and I +certainly don’t have a magic bullet. However, one large conceptual +improvement I think is defaulting to “rebase” versus “merge”.

+ +

This means that we won’t permit direct modification of /etc - instead, +you HAVE to write a script which accomplishes your goals. To generate +a tree, we check out a new copy, then run your script on top.

+ +

If the script fails, we can roll back the update, or drop to a shell +if interactive.

+ +

However, we also need to consider cases where the administrator +modifies state indirectly by a program. Think “adduser” for example.

+ +

Possible approaches:

+ +
    +
  1. Patch all of these programs to know how to write to the writable +location, instead of the R/O bind mount overlay.
  2. +
  3. Move the data to /var
  4. +
+

+ + + What about “packages”? + + +

+ + +

There are several complex and separate issues hiding in this seemingly +simple question.

+ +

I think OSTree always makes sense to use as a core operating system +builder and updater. By “core” here I mean the parts that aren’t +removable. Debian has Essential: yes, any other distribution has this +too implicitly in the set of dependencies for their updater tool.

+ +

Now, let me just say I will absolutely support using something like +apt/yum/zypper (and consequently deb/rpm) on top of OSTree. This +isn’t trivial, but there aren’t any conceptual issues.

+ +

Concretely for example, RPM or .deb might make sense as a delivery +vehicle for third party OS extensions. A canoncial example is the +NVidia graphics driver.

+ +

If one is using OSTree to build an operating system, then there has +to be some API for applications. And that demands its own targeted +solution - something like an evolved glick (zeroinstall is also +similar).

+ +

Current package systems are totally broken for application deployment +though; for example, they will remove files away from under running +applications on update. And we clearly need the ability to install +and upgrade applications without rebooting the OS.

+

+ + + Details of RPM installation + + +

+ + +

We should be able to install LSB rpms. This implies providing “rpm”. +The tricky part here is since the OS itself is not assembled via RPMs, +we need to fake up a database of “provides” as if we were. Even +harder would be maintaining binary compatibilty with any arbitrary +%post scripts that may be run.

+

+ + + What about BTRFS? Doesn’t it solve everything? + + +

+ + +

In short, BTRFS is not a magic bullet, but yes - it helps +significantly. The obvious thing to do is layer BTRFS under dpkg/rpm, +and have a separate subvolume for /home so rollbacks don’t lose your +data. See e.g. +http://fedoraproject.org/wiki/Features/SystemRollbackWithBtrfs

+ +

As a general rule an issue with the BTRFS is that it can’t roll back +just changes to things installed by RPM (i.e. what’s in rpm -qal).

+ +

For example, it’s possible to e.g. run yum update, then edit something +in /etc, reboot and notice things are broken, then roll back and have +silently lost your changes to /etc.

+ +

Another example is adding a new binary in /usr/local. You could say, +“OK, we’ll use subvolumes for those!”. But then what about /var (and +your VM images that live in /var/lib/libvirt ?)

+ +

Finally, probably the biggest disadvantage of the rpm/dpkg + BTRFS +approach is it doesn’t solve the race conditions that happen when +unpacking packages into the live system. This problem is really +important to me.

+ +

Note though ostree can definitely take advantage of BTRFS features! +In particular, we could use “reflink” +http://lwn.net/Articles/331808/ instead of hard links, and avoid +having the object store corrupted if somehow the files are modified +directly.

+

+ + + Other systems + + +

+ + +

I’ve spent a long time thinking about this problem, and here are some +of the other possible solutions out there I looked at, and why I +didn’t use them:

+ +
    +
  • +

    Git: http://git-scm.com/

    + +

    Really awesome, and the core inspiration here. But like I mentioned + above, not at all designed for binaries - we can make different tradeoffs.

    +
  • +
  • +

    bup: https://github.com/apenwarr/bup

    + +

    bup is cool. But it shares the negative tradeoffs with git, though it + does add positives of its own. It also inspired me.

    +
  • +
  • +

    git-annex: http://git-annex.branchable.com/git-annex/

    + +

    Looks interesting; I think this will share the same negative tradeoffs with git +as far as using it for an OS goes.

    +
  • +
  • +

    schroot: http://www.debian-administration.org/articles/566

    + +

    Like LXC/containers, but just using a chroot.

    +
  • +
  • +

    NixOS: http://nixos.org/

    + +

    The NixOS people have a lot of really good ideas, and they’ve definitely + thought about the problem space. However, their approach of checksumming + all inputs to a package is pretty wacky. I don’t see the point, and moreover + it uses gobs of disk space.

    +
  • +
  • +

    Conary: http://wiki.rpath.com/wiki/Conary:Updates_and_Rollbacks

    + +

    If rpm/dpkg are like CVS, Conary is closer to Subversion. It’s not +bad, but ostree is better than it for the exact same reasons git +is better than Subversion.

    +
  • +
  • +

    BTRFS: http://en.wikipedia.org/wiki/Btrfs

    + +

    See above.

    +
  • +
  • +

    Solaris IPS: http://hub.opensolaris.org/bin/view/Project+pkg/

    + +

    Rollback is ZFS level, so I think this shares the same tradeoffs as BTRFS+RPM/deb. +They probably have some vertical integration though which definitely helps. +Obviously we can’t use ZFS.

    +
  • +
  • +

    Jhbuild: https://live.gnome.org/Jhbuild

    + +

    What we’ve been using in GNOME, and has the essential property of allowing you +to “fall back” to a stable system. But ostree will blow it out of the water.

    +
  • +
+

+ + + Development + + +

+ + + + + + + + + + +
+ + + + +
+
+ + + +
+ + +
+ + + + + diff --git a/adapting-existing/index.html b/adapting-existing/index.html new file mode 100644 index 0000000000..bfb4820f4c --- /dev/null +++ b/adapting-existing/index.html @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Adapting existing mainstream distributions | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
+
+ + + + + + + + + + + +
+ +
+ + + + +
+ +

+ + + Adapting existing mainstream distributions + + +

+ + +
    +
  1. System layout
  2. +
  3. Booting and initramfs technology
  4. +
  5. System users and groups
      +
    1. Static users and groups
    2. +
    3. sysusers.d
    4. +
    +
  6. +
  7. Adapting existing package managers
  8. +
+ + +

+ + + System layout + + +

+ + +

First, OSTree encourages systems to implement +UsrMove +This is simply to avoid the need for more bind mounts. By default +OSTree’s dracut hook creates a read-only bind mount over /usr; you +can of course generate individual bind-mounts for /bin, all the +/lib variants, etc. So it is not intended to be a hard requirement.

+ +

Remember, because by default the system is booted into a chroot +equivalent, there has to be some way to refer to the actual physical +root filesystem. Therefore, your operating system tree should contain +an empty /sysroot 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 /ostree which points to /sysroot/ostree, 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.

+ +

Because OSTree only preserves /var 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 Filesystem Hierarchy Standard. +Your operating system may of course choose +not to support some of these such as /usr/local, but following is the +recommended set:

+ +
    +
  • /home/var/home
  • +
  • /opt/var/opt
  • +
  • /srv/var/srv
  • +
  • /root/var/roothome
  • +
  • /usr/local/var/usrlocal
  • +
  • /mnt/var/mnt
  • +
  • /tmp/sysroot/tmp
  • +
+ +

Furthermore, since /var is empty by default, your operating system +will need to dynamically create the targets of these at boot. A +good way to do this is using systemd-tmpfiles, if your OS uses +systemd. For example:

+ +
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 -
+
+ +

However, as of OSTree 2023.9 there is support for a root.transient +model, which can increase compatibility in some scenarios. For more +information, see man ostree-prepare-root.conf.

+ +

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

+

+ + + Booting and initramfs technology + + +

+ + +

OSTree comes with optional dracut+systemd integration code which follows +this logic:

+ +
    +
  • Parse the ostree= kernel command line argument in the initramfs
  • +
  • Set up a read-only bind mount on /usr
  • +
  • Bind mount the deployment’s /sysroot to the physical /
  • +
  • Use mount(MS_MOVE) to make the deployment root appear to be the root filesystem
  • +
+ +

After these steps, systemd switches root.

+ +

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 +src/switchroot +as a reference.

+ +

Patches to support other initramfs technologies and init systems, if +sufficiently clean, will likely be accepted upstream.

+ +

A further specific note regarding sysvinit: OSTree used to support +recording device files such as the /dev/initctl FIFO, but no longer +does. It’s recommended to just patch your initramfs to create this at +boot.

+

+ + + System users and groups + + +

+ + +

Unlike traditional package systems, OSTree trees contain numeric uid +and gids (the same is true of e.g. OCI).

+ +

Furthermore, OSTree does not have a %post type mechanism +where useradd 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 /etc/passwd. The +core problem is that if you add a user to the system for a daemon, the +OSTree upgrade process for /etc will simply notice that because +/etc/passwd differs from the previous default, it will keep the +modified config file, and your new OS user will not be visible.

+ +

First, consider using systemd DynamicUser=yes +where applicable. This entirely avoids problems with static +allocations.

+

+ + + Static users and groups + + +

+ + +

For users which must be allocated statically (for example, they +are used by setuid executables in /usr/bin, there are two +primary wants to handle this.

+ +

The nss-altfiles +was created to pair with image-based update systems like OSTree, +and is used by many operating systems and distributions today.

+ +

More recently, nss-systemd +gained support for statically allocated users and groups in +a JSON format stored in /usr/lib/userdb.

+

+ + + sysusers.d + + +

+ + +

Some users and groups can be assigned dynamically via sysusers.d. This means users and groups are maintained per-machine and may drift (unless statically assigned in sysusers).

+ +

But this model is suitable for users and groups which must always be present, +but do not have file content in the image.

+

+ + + Adapting existing package managers + + +

+ + +

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 +/. This section will use examples from both dpkg and rpm as the +author has familiarity with both; but the abstract concepts should +apply to most traditional package managers.

+ +

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.

+ +

Many package managers store their state in /var; but since in the +OSTree model that directory is shared between independent versions, +the package database must first be found in the per-deployment /usr +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 /var location if the one in /usr +is not found.

+ +

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.

+ +

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 +layering the composed filesystem tree of +these new packages on top. A command like this:

+ +
ostree commit -b osname/releasename/description
+--tree=ref=$osname/$releasename/$description
+--tree=dir=/var/tmp/newpackages.13A8D0/
+
+ +

will create a new commit in the $osname/$releasename/$description +branch. The OSTree SHA256 checksum of all the files in +/var/tmp/newpackages.13A8D0/ 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.

+ +

Then to actually deploy this tree for the next boot: +ostree admin deploy $osname/$releasename/$description

+ +

This is essentially what rpm-ostree +does to support its package layering model.

+ + + + + + + +
+ + + + +
+
+ + + +
+ + +
+ + + + + diff --git a/assets/css/just-the-docs-dark.css b/assets/css/just-the-docs-dark.css new file mode 100644 index 0000000000..58ca8a6807 --- /dev/null +++ b/assets/css/just-the-docs-dark.css @@ -0,0 +1 @@ +.highlight .c{color:#586e75}.highlight .err{color:#93a1a1}.highlight .g{color:#93a1a1}.highlight .k{color:#859900}.highlight .l{color:#93a1a1}.highlight .n{color:#93a1a1}.highlight .o{color:#859900}.highlight .x{color:#cb4b16}.highlight .p{color:#93a1a1}.highlight .cm{color:#586e75}.highlight .cp{color:#859900}.highlight .c1{color:#586e75}.highlight .cs{color:#859900}.highlight .gd{color:#2aa198}.highlight .ge{font-style:italic;color:#93a1a1}.highlight .gr{color:#dc322f}.highlight .gh{color:#cb4b16}.highlight .gi{color:#859900}.highlight .go{color:#93a1a1}.highlight .gp{color:#93a1a1}.highlight .gs{font-weight:bold;color:#93a1a1}.highlight .gu{color:#cb4b16}.highlight .gt{color:#93a1a1}.highlight .kc{color:#cb4b16}.highlight .kd{color:#268bd2}.highlight .kn{color:#859900}.highlight .kp{color:#859900}.highlight .kr{color:#268bd2}.highlight .kt{color:#dc322f}.highlight .ld{color:#93a1a1}.highlight .m{color:#2aa198}.highlight .s{color:#2aa198}.highlight .na{color:#555}.highlight .nb{color:#b58900}.highlight .nc{color:#268bd2}.highlight .no{color:#cb4b16}.highlight .nd{color:#268bd2}.highlight .ni{color:#cb4b16}.highlight .ne{color:#cb4b16}.highlight .nf{color:#268bd2}.highlight .nl{color:#555}.highlight .nn{color:#93a1a1}.highlight .nx{color:#555}.highlight .py{color:#93a1a1}.highlight .nt{color:#268bd2}.highlight .nv{color:#268bd2}.highlight .ow{color:#859900}.highlight .w{color:#93a1a1}.highlight .mf{color:#2aa198}.highlight .mh{color:#2aa198}.highlight .mi{color:#2aa198}.highlight .mo{color:#2aa198}.highlight .sb{color:#586e75}.highlight .sc{color:#2aa198}.highlight .sd{color:#93a1a1}.highlight .s2{color:#2aa198}.highlight .se{color:#cb4b16}.highlight .sh{color:#93a1a1}.highlight .si{color:#2aa198}.highlight .sx{color:#2aa198}.highlight .sr{color:#dc322f}.highlight .s1{color:#2aa198}.highlight .ss{color:#2aa198}.highlight .bp{color:#268bd2}.highlight .vc{color:#268bd2}.highlight .vg{color:#268bd2}.highlight .vi{color:#268bd2}.highlight .il{color:#2aa198}.highlight,pre.highlight{background:#31343f;color:#dee2f7}.highlight pre{background:#31343f}.highlight .hll{background:#31343f}.highlight .c{color:#63677e;font-style:italic}.highlight .err{color:#960050;background-color:#1e0010}.highlight .k{color:#e19ef5}.highlight .l{color:#a3eea0}.highlight .n{color:#dee2f7}.highlight .o{color:#dee2f7}.highlight .p{color:#dee2f7}.highlight .cm{color:#63677e;font-style:italic}.highlight .cp{color:#63677e;font-style:italic}.highlight .c1{color:#63677e;font-style:italic}.highlight .cs{color:#63677e;font-style:italic}.highlight .ge{font-style:italic}.highlight .gs{font-weight:700}.highlight .kc{color:#e19ef5}.highlight .kd{color:#e19ef5}.highlight .kn{color:#e19ef5}.highlight .kp{color:#e19ef5}.highlight .kr{color:#e19ef5}.highlight .kt{color:#e19ef5}.highlight .ld{color:#a3eea0}.highlight .m{color:#eddc96}.highlight .s{color:#a3eea0}.highlight .na{color:#eddc96}.highlight .nb{color:#fdce68}.highlight .nc{color:#fdce68}.highlight .no{color:#fdce68}.highlight .nd{color:#fdce68}.highlight .ni{color:#fdce68}.highlight .ne{color:#fdce68}.highlight .nf{color:#dee2f7}.highlight .nl{color:#fdce68}.highlight .nn{color:#dee2f7}.highlight .nx{color:#dee2f7}.highlight .py{color:#fdce68}.highlight .nt{color:#f9867b}.highlight .nv{color:#fdce68}.highlight .ow{font-weight:700}.highlight .w{color:#f8f8f2}.highlight .mf{color:#eddc96}.highlight .mh{color:#eddc96}.highlight .mi{color:#eddc96}.highlight .mo{color:#eddc96}.highlight .sb{color:#a3eea0}.highlight .sc{color:#a3eea0}.highlight .sd{color:#a3eea0}.highlight .s2{color:#a3eea0}.highlight .se{color:#a3eea0}.highlight .sh{color:#a3eea0}.highlight .si{color:#a3eea0}.highlight .sx{color:#a3eea0}.highlight .sr{color:#7be2f9}.highlight .s1{color:#a3eea0}.highlight .ss{color:#7be2f9}.highlight .bp{color:#fdce68}.highlight .vc{color:#fdce68}.highlight .vg{color:#fdce68}.highlight .vi{color:#f9867b}.highlight .il{color:#eddc96}.highlight .gu{color:#75715e}.highlight .gd{color:#f92672}.highlight .gi{color:#a6e22e}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*{box-sizing:border-box}::selection{color:#fff;background:#2c84fa}html{font-size:14px !important;scroll-behavior:smooth}@media (min-width: 31.25rem){html{font-size:16px !important}}body{font-family:system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;font-size:inherit;line-height:1.4;color:#e6e1e8;background-color:#27262b;overflow-wrap:break-word}ol,ul,dl,pre,address,blockquote,table,div,hr,form,fieldset,noscript .table-wrapper{margin-top:0}h1,h2,h3,h4,h5,h6,#toctitle{margin-top:0;margin-bottom:1em;font-weight:500;line-height:1.25;color:#f5f6fa}p{margin-top:1em;margin-bottom:1em}a{color:#2c84fa;text-decoration:none}a:not([class]){text-decoration:underline;text-decoration-color:#44434d;text-underline-offset:2px}a:not([class]):hover{text-decoration-color:rgba(44,132,250,0.45)}code{font-family:"SFMono-Regular",menlo,consolas,monospace;font-size:0.75em;line-height:1.4}figure,pre{margin:0}li{margin:0.25em 0}img{max-width:100%;height:auto}hr{height:1px;padding:0;margin:2rem 0;background-color:#44434d;border:0}blockquote{margin:10px 0;margin-block-start:0;margin-inline-start:0;padding-left:15px;border-left:3px solid #44434d}.side-bar{z-index:0;display:flex;flex-wrap:wrap;background-color:#27262b}@media (min-width: 50rem){.side-bar{flex-flow:column nowrap;position:fixed;width:248px;height:100%;border-right:1px solid #44434d;align-items:flex-end}}@media (min-width: 66.5rem){.side-bar{width:calc((100% - 1064px) / 2 + 264px);min-width:264px}}@media (min-width: 50rem){.main{position:relative;max-width:800px;margin-left:248px}}@media (min-width: 66.5rem){.main{margin-left:Max(264px, calc((100% - 1064px) / 2 + 264px))}}.main-content-wrap{padding-right:1rem;padding-left:1rem;padding-top:1rem;padding-bottom:1rem}@media (min-width: 50rem){.main-content-wrap{padding-right:2rem;padding-left:2rem}}@media (min-width: 50rem){.main-content-wrap{padding-top:2rem;padding-bottom:2rem}}.main-header{z-index:0;display:none;background-color:#27262b}@media (min-width: 50rem){.main-header{display:flex;justify-content:space-between;height:60px;background-color:#27262b;border-bottom:1px solid #44434d}}.main-header.nav-open{display:block}@media (min-width: 50rem){.main-header.nav-open{display:flex}}.site-nav,.site-header,.site-footer{width:100%}@media (min-width: 66.5rem){.site-nav,.site-header,.site-footer{width:264px}}.site-nav{display:none}.site-nav.nav-open{display:block}@media (min-width: 50rem){.site-nav{display:block;padding-top:3rem;padding-bottom:1rem;overflow-y:auto;flex:1 1 auto}}.site-header{display:flex;min-height:60px;align-items:center}@media (min-width: 50rem){.site-header{height:60px;max-height:60px;border-bottom:1px solid #44434d}}.site-title{padding-right:1rem;padding-left:1rem;flex-grow:1;display:flex;height:100%;align-items:center;padding-top:.75rem;padding-bottom:.75rem;color:#f5f6fa;font-size:18px !important}@media (min-width: 50rem){.site-title{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-title{font-size:24px !important;line-height:1.25}}@media (min-width: 50rem){.site-title{padding-top:.5rem;padding-bottom:.5rem}}.site-button{display:flex;height:100%;padding:1rem;align-items:center}@media (min-width: 50rem){.site-header .site-button{display:none}}.site-title:hover{background-image:linear-gradient(-90deg, #201f23 0%, rgba(32,31,35,0.8) 80%, rgba(32,31,35,0) 100%)}.site-button:hover{background-image:linear-gradient(-90deg, #201f23 0%, rgba(32,31,35,0.8) 100%)}body{position:relative;padding-bottom:4rem;overflow-y:scroll}@media (min-width: 50rem){body{position:static;padding-bottom:0}}.site-footer{padding-right:1rem;padding-left:1rem;position:absolute;bottom:0;left:0;padding-top:1rem;padding-bottom:1rem;color:#959396;font-size:11px !important}@media (min-width: 50rem){.site-footer{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-footer{font-size:12px !important}}@media (min-width: 50rem){.site-footer{position:static;justify-self:end}}.icon{width:1.5rem;height:1.5rem;color:#2c84fa}.main-content{line-height:1.6}.main-content ol,.main-content ul,.main-content dl,.main-content pre,.main-content address,.main-content blockquote,.main-content .table-wrapper{margin-top:0.5em}.main-content a{overflow:hidden;text-overflow:ellipsis}.main-content ul,.main-content ol{padding-left:1.5em}.main-content li .highlight{margin-top:.25rem}.main-content ol{list-style-type:none;counter-reset:step-counter}.main-content ol>li{position:relative}.main-content ol>li::before{position:absolute;top:0.2em;left:-1.6em;color:#959396;content:counter(step-counter);counter-increment:step-counter;font-size:12px !important}@media (min-width: 31.25rem){.main-content ol>li::before{font-size:14px !important}}@media (min-width: 31.25rem){.main-content ol>li::before{top:0.11em}}.main-content ol>li ol{counter-reset:sub-counter}.main-content ol>li ol>li::before{content:counter(sub-counter,lower-alpha);counter-increment:sub-counter}.main-content ul{list-style:none}.main-content ul>li::before{position:absolute;margin-left:-1.4em;color:#959396;content:"•"}.main-content .task-list-item::before{content:""}.main-content .task-list-item-checkbox{margin-right:0.6em;margin-left:-1.4em}.main-content hr+*{margin-top:0}.main-content h1:first-of-type{margin-top:0.5em}.main-content dl{display:grid;grid-template:auto / 10em 1fr}.main-content dt,.main-content dd{margin:0.25em 0}.main-content dt{grid-column:1;font-weight:500;text-align:right}.main-content dt::after{content:":"}.main-content dd{grid-column:2;margin-bottom:0;margin-left:1em}.main-content dd blockquote:first-child,.main-content dd div:first-child,.main-content dd dl:first-child,.main-content dd dt:first-child,.main-content dd h1:first-child,.main-content dd h2:first-child,.main-content dd h3:first-child,.main-content dd h4:first-child,.main-content dd h5:first-child,.main-content dd h6:first-child,.main-content dd li:first-child,.main-content dd ol:first-child,.main-content dd p:first-child,.main-content dd pre:first-child,.main-content dd table:first-child,.main-content dd ul:first-child,.main-content dd .table-wrapper:first-child{margin-top:0}.main-content dd dl:first-child dt:first-child,.main-content dd dl:first-child dd:nth-child(2),.main-content ol dl:first-child dt:first-child,.main-content ol dl:first-child dd:nth-child(2),.main-content ul dl:first-child dt:first-child,.main-content ul dl:first-child dd:nth-child(2){margin-top:0}.main-content .anchor-heading{position:absolute;right:-1rem;width:1.5rem;height:100%;padding-right:.25rem;padding-left:.25rem;overflow:visible}@media (min-width: 50rem){.main-content .anchor-heading{right:auto;left:-1.5rem}}.main-content .anchor-heading svg{display:inline-block;width:100%;height:100%;color:#2c84fa;visibility:hidden}.main-content .anchor-heading:hover svg,.main-content .anchor-heading:focus svg,.main-content h1:hover>.anchor-heading svg,.main-content h2:hover>.anchor-heading svg,.main-content h3:hover>.anchor-heading svg,.main-content h4:hover>.anchor-heading svg,.main-content h5:hover>.anchor-heading svg,.main-content h6:hover>.anchor-heading svg{visibility:visible}.main-content summary{cursor:pointer}.main-content h1,.main-content h2,.main-content h3,.main-content h4,.main-content h5,.main-content h6,.main-content #toctitle{position:relative;margin-top:1.5em;margin-bottom:0.25em}.main-content h1+table,.main-content h1+.table-wrapper,.main-content h1+.code-example,.main-content h1+.highlighter-rouge,.main-content h1+.sectionbody .listingblock,.main-content h2+table,.main-content h2+.table-wrapper,.main-content h2+.code-example,.main-content h2+.highlighter-rouge,.main-content h2+.sectionbody .listingblock,.main-content h3+table,.main-content h3+.table-wrapper,.main-content h3+.code-example,.main-content h3+.highlighter-rouge,.main-content h3+.sectionbody .listingblock,.main-content h4+table,.main-content h4+.table-wrapper,.main-content h4+.code-example,.main-content h4+.highlighter-rouge,.main-content h4+.sectionbody .listingblock,.main-content h5+table,.main-content h5+.table-wrapper,.main-content h5+.code-example,.main-content h5+.highlighter-rouge,.main-content h5+.sectionbody .listingblock,.main-content h6+table,.main-content h6+.table-wrapper,.main-content h6+.code-example,.main-content h6+.highlighter-rouge,.main-content h6+.sectionbody .listingblock,.main-content #toctitle+table,.main-content #toctitle+.table-wrapper,.main-content #toctitle+.code-example,.main-content #toctitle+.highlighter-rouge,.main-content #toctitle+.sectionbody .listingblock{margin-top:1em}.main-content h1+p:not(.label),.main-content h2+p:not(.label),.main-content h3+p:not(.label),.main-content h4+p:not(.label),.main-content h5+p:not(.label),.main-content h6+p:not(.label),.main-content #toctitle+p:not(.label){margin-top:0}.main-content>h1:first-child,.main-content>h2:first-child,.main-content>h3:first-child,.main-content>h4:first-child,.main-content>h5:first-child,.main-content>h6:first-child,.main-content>.sect1:first-child>h2,.main-content>.sect2:first-child>h3,.main-content>.sect3:first-child>h4,.main-content>.sect4:first-child>h5,.main-content>.sect5:first-child>h6{margin-top:.5rem}.nav-list{padding:0;margin-top:0;margin-bottom:0;list-style:none}.nav-list .nav-list-item{font-size:14px !important;position:relative;margin:0}@media (min-width: 31.25rem){.nav-list .nav-list-item{font-size:16px !important}}@media (min-width: 50rem){.nav-list .nav-list-item{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.nav-list .nav-list-item{font-size:14px !important}}.nav-list .nav-list-item .nav-list-link{display:block;min-height:3rem;padding-top:.25rem;padding-bottom:.25rem;line-height:2.5rem;padding-right:3rem;padding-left:1rem}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-link{min-height:2rem;line-height:1.5rem;padding-right:2rem;padding-left:2rem}}.nav-list .nav-list-item .nav-list-link.external>svg{width:1rem;height:1rem;vertical-align:text-bottom}.nav-list .nav-list-item .nav-list-link.active{font-weight:600;text-decoration:none}.nav-list .nav-list-item .nav-list-link:hover,.nav-list .nav-list-item .nav-list-link.active{background-image:linear-gradient(-90deg, #201f23 0%, rgba(32,31,35,0.8) 80%, rgba(32,31,35,0) 100%)}.nav-list .nav-list-item .nav-list-expander{position:absolute;right:0;width:3rem;height:3rem;padding:.75rem;color:#2c84fa}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-expander{width:2rem;height:2rem;padding:.5rem}}.nav-list .nav-list-item .nav-list-expander:hover{background-image:linear-gradient(-90deg, #201f23 0%, rgba(32,31,35,0.8) 100%)}.nav-list .nav-list-item .nav-list-expander svg{transform:rotate(90deg)}.nav-list .nav-list-item>.nav-list{display:none;padding-left:.75rem;list-style:none}.nav-list .nav-list-item>.nav-list .nav-list-item{position:relative}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-link{color:#959396}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-expander{color:#959396}.nav-list .nav-list-item.active>.nav-list-expander svg{transform:rotate(-90deg)}.nav-list .nav-list-item.active>.nav-list{display:block}.nav-category{padding:.5rem 1rem;font-weight:600;text-align:start;text-transform:uppercase;border-bottom:1px solid #44434d;font-size:11px !important}@media (min-width: 31.25rem){.nav-category{font-size:12px !important}}@media (min-width: 50rem){.nav-category{padding:.5rem 2rem;margin-top:1rem;text-align:start}.nav-category:first-child{margin-top:0}}.nav-list.nav-category-list>.nav-list-item{margin:0}.nav-list.nav-category-list>.nav-list-item>.nav-list{padding:0}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-link{color:#2c84fa}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-expander{color:#2c84fa}.aux-nav{height:100%;overflow-x:auto;font-size:11px !important}@media (min-width: 31.25rem){.aux-nav{font-size:12px !important}}.aux-nav .aux-nav-list{display:flex;height:100%;padding:0;margin:0;list-style:none}.aux-nav .aux-nav-list-item{display:inline-block;height:100%;padding:0;margin:0}@media (min-width: 50rem){.aux-nav{padding-right:1rem}}@media (min-width: 50rem){.breadcrumb-nav{margin-top:-1rem}}.breadcrumb-nav-list{padding-left:0;margin-bottom:.75rem;list-style:none}.breadcrumb-nav-list-item{display:table-cell;font-size:11px !important}@media (min-width: 31.25rem){.breadcrumb-nav-list-item{font-size:12px !important}}.breadcrumb-nav-list-item::before{display:none}.breadcrumb-nav-list-item::after{display:inline-block;margin-right:.5rem;margin-left:.5rem;color:#959396;content:"/"}.breadcrumb-nav-list-item:last-child::after{content:""}h1,.text-alpha{font-size:32px !important;line-height:1.25;font-weight:300}@media (min-width: 31.25rem){h1,.text-alpha{font-size:36px !important}}h2,.text-beta,#toctitle{font-size:18px !important}@media (min-width: 31.25rem){h2,.text-beta,#toctitle{font-size:24px !important;line-height:1.25}}h3,.text-gamma{font-size:16px !important}@media (min-width: 31.25rem){h3,.text-gamma{font-size:18px !important}}h4,.text-delta{font-size:11px !important;font-weight:400;text-transform:uppercase;letter-spacing:0.1em}@media (min-width: 31.25rem){h4,.text-delta{font-size:12px !important}}h4 code{text-transform:none}h5,.text-epsilon{font-size:12px !important}@media (min-width: 31.25rem){h5,.text-epsilon{font-size:14px !important}}h6,.text-zeta{font-size:11px !important}@media (min-width: 31.25rem){h6,.text-zeta{font-size:12px !important}}.text-small{font-size:11px !important}@media (min-width: 31.25rem){.text-small{font-size:12px !important}}.text-mono{font-family:"SFMono-Regular",menlo,consolas,monospace !important}.text-left{text-align:left !important}.text-center{text-align:center !important}.text-right{text-align:right !important}.label,.label-blue{display:inline-block;padding:0.16em 0.56em;margin-right:.5rem;margin-left:.5rem;color:#fff;text-transform:uppercase;vertical-align:middle;background-color:#2869e6;font-size:11px !important;border-radius:12px}@media (min-width: 31.25rem){.label,.label-blue{font-size:12px !important}}.label-green{background-color:#009c7b}.label-purple{background-color:#5e41d0}.label-red{background-color:#e94c4c}.label-yellow{color:#44434d;background-color:#f7d12e}.btn{display:inline-block;box-sizing:border-box;padding:0.3em 1em;margin:0;font-family:inherit;font-size:inherit;font-weight:500;line-height:1.5;color:#2c84fa;text-decoration:none;vertical-align:baseline;cursor:pointer;background-color:#302d36;border-width:0;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);appearance:none}.btn:focus{text-decoration:none;outline:none;box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:focus:hover,.btn.selected:focus{box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:hover,.btn.zeroclipboard-is-hover{color:#227efa}.btn:hover,.btn:active,.btn.zeroclipboard-is-hover,.btn.zeroclipboard-is-active{text-decoration:none;background-color:#2e2b33}.btn:active,.btn.selected,.btn.zeroclipboard-is-active{background-color:#29262e;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn.selected:hover{background-color:#cfcfcf}.btn:disabled,.btn:disabled:hover,.btn.disabled,.btn.disabled:hover{color:rgba(102,102,102,0.5);cursor:default;background-color:rgba(229,229,229,0.5);background-image:none;box-shadow:none}.btn-outline{color:#2c84fa;background:transparent;box-shadow:inset 0 0 0 2px #e6e1e8}.btn-outline:hover,.btn-outline:active,.btn-outline.zeroclipboard-is-hover,.btn-outline.zeroclipboard-is-active{color:#1878fa;text-decoration:none;background-color:transparent;box-shadow:inset 0 0 0 3px #e6e1e8}.btn-outline:focus{text-decoration:none;outline:none;box-shadow:inset 0 0 0 2px #5c5962,0 0 0 3px rgba(0,0,255,0.25)}.btn-outline:focus:hover,.btn-outline.selected:focus{box-shadow:inset 0 0 0 2px #5c5962}.btn-primary{color:#fff;background-color:#2448a7;background-image:linear-gradient(#2b55c4, #2448a7);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-primary:hover,.btn-primary.zeroclipboard-is-hover{color:#fff;background-color:#22459e;background-image:linear-gradient(#2850b7,#22459e)}.btn-primary:active,.btn-primary.selected,.btn-primary.zeroclipboard-is-active{background-color:#21439a;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-primary.selected:hover{background-color:#1d3a85}.btn-purple{color:#fff;background-color:#5739ce;background-image:linear-gradient(#6f55d5, #5739ce);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-purple:hover,.btn-purple.zeroclipboard-is-hover{color:#fff;background-color:#5132cb;background-image:linear-gradient(#6549d2,#5132cb)}.btn-purple:active,.btn-purple.selected,.btn-purple.zeroclipboard-is-active{background-color:#4f31c6;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-purple.selected:hover{background-color:#472cb2}.btn-blue{color:#fff;background-color:#227efa;background-image:linear-gradient(#4593fb, #227efa);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-blue:hover,.btn-blue.zeroclipboard-is-hover{color:#fff;background-color:#1878fa;background-image:linear-gradient(#368afa,#1878fa)}.btn-blue:active,.btn-blue.selected,.btn-blue.zeroclipboard-is-active{background-color:#1375f9;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-blue.selected:hover{background-color:#0669ed}.btn-green{color:#fff;background-color:#10ac7d;background-image:linear-gradient(#13cc95, #10ac7d);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-green:hover,.btn-green.zeroclipboard-is-hover{color:#fff;background-color:#0fa276;background-image:linear-gradient(#12be8b,#0fa276)}.btn-green:active,.btn-green.selected,.btn-green.zeroclipboard-is-active{background-color:#0f9e73;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-green.selected:hover{background-color:#0d8662}.search{position:relative;z-index:2;flex-grow:1;height:4rem;padding:.5rem;transition:padding linear 200ms}@media (min-width: 50rem){.search{position:relative !important;width:auto !important;height:100% !important;padding:0;transition:none}}.search-input-wrap{position:relative;z-index:1;height:3rem;overflow:hidden;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);transition:height linear 200ms}@media (min-width: 50rem){.search-input-wrap{position:absolute;width:100%;max-width:536px;height:100% !important;border-radius:0;box-shadow:none;transition:width ease 400ms}}.search-input{position:absolute;width:100%;height:100%;padding:.5rem 1rem .5rem 2.5rem;font-size:16px;color:#e6e1e8;background-color:#302d36;border-top:0;border-right:0;border-bottom:0;border-left:0;border-radius:0}@media (min-width: 50rem){.search-input{padding:.5rem 1rem .5rem 3.5rem;font-size:14px;background-color:#27262b;transition:padding-left linear 200ms}}.search-input:focus{outline:0}.search-input:focus+.search-label .search-icon{color:#2c84fa}.search-label{position:absolute;display:flex;height:100%;padding-left:1rem}@media (min-width: 50rem){.search-label{padding-left:2rem;transition:padding-left linear 200ms}}.search-label .search-icon{width:1.2rem;height:1.2rem;align-self:center;color:#959396}.search-results{position:absolute;left:0;display:none;width:100%;max-height:calc(100% - 4rem);overflow-y:auto;background-color:#302d36;border-bottom-right-radius:4px;border-bottom-left-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}@media (min-width: 50rem){.search-results{top:100%;width:536px;max-height:calc(100vh - 200%) !important}}.search-results-list{padding-left:0;margin-bottom:.25rem;list-style:none;font-size:14px !important}@media (min-width: 31.25rem){.search-results-list{font-size:16px !important}}@media (min-width: 50rem){.search-results-list{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-results-list{font-size:14px !important}}.search-results-list-item{padding:0;margin:0}.search-result{display:block;padding:.25rem .75rem}.search-result:hover,.search-result.active{background-color:#201f23}.search-result-title{display:block;padding-top:.5rem;padding-bottom:.5rem}@media (min-width: 31.25rem){.search-result-title{display:inline-block;width:40%;padding-right:.5rem;vertical-align:top}}.search-result-doc{display:flex;align-items:center;word-wrap:break-word}.search-result-doc.search-result-doc-parent{opacity:0.5;font-size:12px !important}@media (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:14px !important}}@media (min-width: 50rem){.search-result-doc.search-result-doc-parent{font-size:11px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:12px !important}}.search-result-doc .search-result-icon{width:1rem;height:1rem;margin-right:.5rem;color:#2c84fa;flex-shrink:0}.search-result-doc .search-result-doc-title{overflow:auto}.search-result-section{margin-left:1.5rem;word-wrap:break-word}.search-result-rel-url{display:block;margin-left:1.5rem;overflow:hidden;color:#959396;text-overflow:ellipsis;white-space:nowrap;font-size:9px !important}@media (min-width: 31.25rem){.search-result-rel-url{font-size:10px !important}}.search-result-previews{display:block;padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;margin-left:.5rem;color:#959396;word-wrap:break-word;border-left:1px solid;border-left-color:#44434d;font-size:11px !important}@media (min-width: 31.25rem){.search-result-previews{font-size:12px !important}}@media (min-width: 31.25rem){.search-result-previews{display:inline-block;width:60%;padding-left:.5rem;margin-left:0;vertical-align:top}}.search-result-preview+.search-result-preview{margin-top:.25rem}.search-result-highlight{font-weight:bold}.search-no-result{padding:.5rem .75rem;font-size:12px !important}@media (min-width: 31.25rem){.search-no-result{font-size:14px !important}}.search-button{position:fixed;right:1rem;bottom:1rem;display:flex;width:3.5rem;height:3.5rem;background-color:#302d36;border:1px solid rgba(44,132,250,0.3);border-radius:1.75rem;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);align-items:center;justify-content:center}.search-overlay{position:fixed;top:0;left:0;z-index:1;width:0;height:0;background-color:rgba(0,0,0,0.3);opacity:0;transition:opacity ease 400ms,width 0s 400ms,height 0s 400ms}.search-active .search{position:fixed;top:0;left:0;width:100%;height:100%;padding:0}.search-active .search-input-wrap{height:4rem;border-radius:0}@media (min-width: 50rem){.search-active .search-input-wrap{width:536px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}}.search-active .search-input{background-color:#302d36}@media (min-width: 50rem){.search-active .search-input{padding-left:2.3rem}}@media (min-width: 50rem){.search-active .search-label{padding-left:0.6rem}}.search-active .search-results{display:block}.search-active .search-overlay{width:100%;height:100%;opacity:1;transition:opacity ease 400ms,width 0s,height 0s}@media (min-width: 50rem){.search-active .main{position:fixed;right:0;left:0}}.search-active .main-header{padding-top:4rem}@media (min-width: 50rem){.search-active .main-header{padding-top:0}}.table-wrapper{display:block;width:100%;max-width:100%;margin-bottom:1.5rem;overflow-x:auto;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}table{display:table;min-width:100%;border-collapse:separate}th,td{font-size:12px !important;min-width:120px;padding:.5rem .75rem;background-color:#302d36;border-bottom:1px solid rgba(68,67,77,0.5);border-left:1px solid #44434d}@media (min-width: 31.25rem){th,td{font-size:14px !important}}th:first-of-type,td:first-of-type{border-left:0}tbody tr:last-of-type th,tbody tr:last-of-type td{border-bottom:0}tbody tr:last-of-type td{padding-bottom:.75rem}thead th{border-bottom:1px solid #44434d}:not(pre,figure)>code{padding:0.2em 0.15em;font-weight:400;background-color:#31343f;border:1px solid #44434d;border-radius:4px}a:visited code{border-color:#44434d}div.highlighter-rouge,div.listingblock>div.content,figure.highlight{margin-top:0;margin-bottom:.75rem;background-color:#31343f;border-radius:4px;box-shadow:none;-webkit-overflow-scrolling:touch;position:relative;padding:0}div.highlighter-rouge>button,div.listingblock>div.content>button,figure.highlight>button{width:.75rem;opacity:0;position:absolute;top:0;right:0;border:.75rem solid #31343f;background-color:#31343f;color:#e6e1e8;box-sizing:content-box}div.highlighter-rouge>button svg,div.listingblock>div.content>button svg,figure.highlight>button svg{fill:#e6e1e8}div.highlighter-rouge>button:active,div.listingblock>div.content>button:active,figure.highlight>button:active{text-decoration:none;outline:none;opacity:1}div.highlighter-rouge>button:focus,div.listingblock>div.content>button:focus,figure.highlight>button:focus{opacity:1}div.highlighter-rouge:hover>button,div.listingblock>div.content:hover>button,figure.highlight:hover>button{cursor:copy;opacity:1}div.highlighter-rouge div.highlight{overflow-x:auto;padding:.75rem;margin:0;border:0}div.highlighter-rouge pre.highlight,div.highlighter-rouge code{padding:0;margin:0;border:0}div.listingblock{margin-top:0;margin-bottom:.75rem}div.listingblock div.content{overflow-x:auto;padding:.75rem;margin:0;border:0}div.listingblock div.content>pre,div.listingblock code{padding:0;margin:0;border:0}figure.highlight pre,figure.highlight :not(pre)>code{overflow-x:auto;padding:.75rem;margin:0;border:0}.highlight .table-wrapper{padding:.75rem 0;margin:0;border:0;box-shadow:none}.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:11px !important;min-width:0;padding:0;background-color:#31343f;border:0}@media (min-width: 31.25rem){.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:12px !important}}.highlight .table-wrapper td.gl{width:1em;padding-right:.75rem;padding-left:.75rem}.highlight .table-wrapper pre{margin:0;line-height:2}.code-example,.listingblock>.title{padding:.75rem;margin-bottom:.75rem;overflow:auto;border:1px solid #44434d;border-radius:4px}.code-example+.highlighter-rouge,.code-example+.sectionbody .listingblock,.code-example+.content,.code-example+figure.highlight,.listingblock>.title+.highlighter-rouge,.listingblock>.title+.sectionbody .listingblock,.listingblock>.title+.content,.listingblock>.title+figure.highlight{position:relative;margin-top:-1rem;border-right:1px solid #44434d;border-bottom:1px solid #44434d;border-left:1px solid #44434d;border-top-left-radius:0;border-top-right-radius:0}code.language-mermaid{padding:0;background-color:inherit;border:0}.highlight,pre.highlight{background:#31343f;color:#dee2f7}.highlight pre{background:#31343f}.text-grey-dk-000{color:#959396 !important}.text-grey-dk-100{color:#5c5962 !important}.text-grey-dk-200{color:#44434d !important}.text-grey-dk-250{color:#302d36 !important}.text-grey-dk-300{color:#27262b !important}.text-grey-lt-000{color:#f5f6fa !important}.text-grey-lt-100{color:#eeebee !important}.text-grey-lt-200{color:#ecebed !important}.text-grey-lt-300{color:#e6e1e8 !important}.text-blue-000{color:#2c84fa !important}.text-blue-100{color:#2869e6 !important}.text-blue-200{color:#264caf !important}.text-blue-300{color:#183385 !important}.text-green-000{color:#41d693 !important}.text-green-100{color:#11b584 !important}.text-green-200{color:#009c7b !important}.text-green-300{color:#026e57 !important}.text-purple-000{color:#7253ed !important}.text-purple-100{color:#5e41d0 !important}.text-purple-200{color:#4e26af !important}.text-purple-300{color:#381885 !important}.text-yellow-000{color:#ffeb82 !important}.text-yellow-100{color:#fadf50 !important}.text-yellow-200{color:#f7d12e !important}.text-yellow-300{color:#e7af06 !important}.text-red-000{color:#f77e7e !important}.text-red-100{color:#f96e65 !important}.text-red-200{color:#e94c4c !important}.text-red-300{color:#dd2e2e !important}.bg-grey-dk-000{background-color:#959396 !important}.bg-grey-dk-100{background-color:#5c5962 !important}.bg-grey-dk-200{background-color:#44434d !important}.bg-grey-dk-250{background-color:#302d36 !important}.bg-grey-dk-300{background-color:#27262b !important}.bg-grey-lt-000{background-color:#f5f6fa !important}.bg-grey-lt-100{background-color:#eeebee !important}.bg-grey-lt-200{background-color:#ecebed !important}.bg-grey-lt-300{background-color:#e6e1e8 !important}.bg-blue-000{background-color:#2c84fa !important}.bg-blue-100{background-color:#2869e6 !important}.bg-blue-200{background-color:#264caf !important}.bg-blue-300{background-color:#183385 !important}.bg-green-000{background-color:#41d693 !important}.bg-green-100{background-color:#11b584 !important}.bg-green-200{background-color:#009c7b !important}.bg-green-300{background-color:#026e57 !important}.bg-purple-000{background-color:#7253ed !important}.bg-purple-100{background-color:#5e41d0 !important}.bg-purple-200{background-color:#4e26af !important}.bg-purple-300{background-color:#381885 !important}.bg-yellow-000{background-color:#ffeb82 !important}.bg-yellow-100{background-color:#fadf50 !important}.bg-yellow-200{background-color:#f7d12e !important}.bg-yellow-300{background-color:#e7af06 !important}.bg-red-000{background-color:#f77e7e !important}.bg-red-100{background-color:#f96e65 !important}.bg-red-200{background-color:#e94c4c !important}.bg-red-300{background-color:#dd2e2e !important}.d-block{display:block !important}.d-flex{display:flex !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-none{display:none !important}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}.float-left{float:left !important}.float-right{float:right !important}.flex-justify-start{justify-content:flex-start !important}.flex-justify-end{justify-content:flex-end !important}.flex-justify-between{justify-content:space-between !important}.flex-justify-around{justify-content:space-around !important}.v-align-baseline{vertical-align:baseline !important}.v-align-bottom{vertical-align:bottom !important}.v-align-middle{vertical-align:middle !important}.v-align-text-bottom{vertical-align:text-bottom !important}.v-align-text-top{vertical-align:text-top !important}.v-align-top{vertical-align:top !important}.fs-1{font-size:9px !important}@media (min-width: 31.25rem){.fs-1{font-size:10px !important}}.fs-2{font-size:11px !important}@media (min-width: 31.25rem){.fs-2{font-size:12px !important}}.fs-3{font-size:12px !important}@media (min-width: 31.25rem){.fs-3{font-size:14px !important}}.fs-4{font-size:14px !important}@media (min-width: 31.25rem){.fs-4{font-size:16px !important}}.fs-5{font-size:16px !important}@media (min-width: 31.25rem){.fs-5{font-size:18px !important}}.fs-6{font-size:18px !important}@media (min-width: 31.25rem){.fs-6{font-size:24px !important;line-height:1.25}}.fs-7{font-size:24px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-7{font-size:32px !important}}.fs-8{font-size:32px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-8{font-size:36px !important}}.fs-9{font-size:36px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-9{font-size:42px !important}}.fs-10{font-size:42px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-10{font-size:48px !important}}.fw-300{font-weight:300 !important}.fw-400{font-weight:400 !important}.fw-500{font-weight:500 !important}.fw-700{font-weight:700 !important}.lh-0{line-height:0 !important}.lh-default{line-height:1.4}.lh-tight{line-height:1.25}.ls-5{letter-spacing:0.05em !important}.ls-10{letter-spacing:0.1em !important}.ls-0{letter-spacing:0 !important}.text-uppercase{text-transform:uppercase !important}.list-style-none{padding:0 !important;margin:0 !important;list-style:none !important}.list-style-none li::before{display:none !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-0{margin-right:-0 !important;margin-left:-0 !important}.mx-0-auto{margin-right:auto !important;margin-left:auto !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-1{margin-right:-.25rem !important;margin-left:-.25rem !important}.mx-1-auto{margin-right:auto !important;margin-left:auto !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-2{margin-right:-.5rem !important;margin-left:-.5rem !important}.mx-2-auto{margin-right:auto !important;margin-left:auto !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-3{margin-right:-.75rem !important;margin-left:-.75rem !important}.mx-3-auto{margin-right:auto !important;margin-left:auto !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-right:1rem !important;margin-left:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-4{margin-right:-1rem !important;margin-left:-1rem !important}.mx-4-auto{margin-right:auto !important;margin-left:auto !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}.mx-5-auto{margin-right:auto !important;margin-left:auto !important}.m-6{margin:2rem !important}.mt-6{margin-top:2rem !important}.mr-6{margin-right:2rem !important}.mb-6{margin-bottom:2rem !important}.ml-6{margin-left:2rem !important}.mx-6{margin-right:2rem !important;margin-left:2rem !important}.my-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-6{margin-right:-2rem !important;margin-left:-2rem !important}.mx-6-auto{margin-right:auto !important;margin-left:auto !important}.m-7{margin:2.5rem !important}.mt-7{margin-top:2.5rem !important}.mr-7{margin-right:2.5rem !important}.mb-7{margin-bottom:2.5rem !important}.ml-7{margin-left:2.5rem !important}.mx-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}.mx-7-auto{margin-right:auto !important;margin-left:auto !important}.m-8{margin:3rem !important}.mt-8{margin-top:3rem !important}.mr-8{margin-right:3rem !important}.mb-8{margin-bottom:3rem !important}.ml-8{margin-left:3rem !important}.mx-8{margin-right:3rem !important;margin-left:3rem !important}.my-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-8{margin-right:-3rem !important;margin-left:-3rem !important}.mx-8-auto{margin-right:auto !important;margin-left:auto !important}.m-9{margin:3.5rem !important}.mt-9{margin-top:3.5rem !important}.mr-9{margin-right:3.5rem !important}.mb-9{margin-bottom:3.5rem !important}.ml-9{margin-left:3.5rem !important}.mx-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}.mx-9-auto{margin-right:auto !important;margin-left:auto !important}.m-10{margin:4rem !important}.mt-10{margin-top:4rem !important}.mr-10{margin-right:4rem !important}.mb-10{margin-bottom:4rem !important}.ml-10{margin-left:4rem !important}.mx-10{margin-right:4rem !important;margin-left:4rem !important}.my-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-10{margin-right:-4rem !important;margin-left:-4rem !important}.mx-10-auto{margin-right:auto !important;margin-left:auto !important}@media (min-width: 20rem){.m-xs-0{margin:0 !important}.mt-xs-0{margin-top:0 !important}.mr-xs-0{margin-right:0 !important}.mb-xs-0{margin-bottom:0 !important}.ml-xs-0{margin-left:0 !important}.mx-xs-0{margin-right:0 !important;margin-left:0 !important}.my-xs-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xs-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 20rem){.m-xs-1{margin:.25rem !important}.mt-xs-1{margin-top:.25rem !important}.mr-xs-1{margin-right:.25rem !important}.mb-xs-1{margin-bottom:.25rem !important}.ml-xs-1{margin-left:.25rem !important}.mx-xs-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xs-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xs-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 20rem){.m-xs-2{margin:.5rem !important}.mt-xs-2{margin-top:.5rem !important}.mr-xs-2{margin-right:.5rem !important}.mb-xs-2{margin-bottom:.5rem !important}.ml-xs-2{margin-left:.5rem !important}.mx-xs-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xs-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xs-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 20rem){.m-xs-3{margin:.75rem !important}.mt-xs-3{margin-top:.75rem !important}.mr-xs-3{margin-right:.75rem !important}.mb-xs-3{margin-bottom:.75rem !important}.ml-xs-3{margin-left:.75rem !important}.mx-xs-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xs-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xs-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 20rem){.m-xs-4{margin:1rem !important}.mt-xs-4{margin-top:1rem !important}.mr-xs-4{margin-right:1rem !important}.mb-xs-4{margin-bottom:1rem !important}.ml-xs-4{margin-left:1rem !important}.mx-xs-4{margin-right:1rem !important;margin-left:1rem !important}.my-xs-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xs-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 20rem){.m-xs-5{margin:1.5rem !important}.mt-xs-5{margin-top:1.5rem !important}.mr-xs-5{margin-right:1.5rem !important}.mb-xs-5{margin-bottom:1.5rem !important}.ml-xs-5{margin-left:1.5rem !important}.mx-xs-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xs-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xs-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 20rem){.m-xs-6{margin:2rem !important}.mt-xs-6{margin-top:2rem !important}.mr-xs-6{margin-right:2rem !important}.mb-xs-6{margin-bottom:2rem !important}.ml-xs-6{margin-left:2rem !important}.mx-xs-6{margin-right:2rem !important;margin-left:2rem !important}.my-xs-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xs-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 20rem){.m-xs-7{margin:2.5rem !important}.mt-xs-7{margin-top:2.5rem !important}.mr-xs-7{margin-right:2.5rem !important}.mb-xs-7{margin-bottom:2.5rem !important}.ml-xs-7{margin-left:2.5rem !important}.mx-xs-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xs-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xs-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 20rem){.m-xs-8{margin:3rem !important}.mt-xs-8{margin-top:3rem !important}.mr-xs-8{margin-right:3rem !important}.mb-xs-8{margin-bottom:3rem !important}.ml-xs-8{margin-left:3rem !important}.mx-xs-8{margin-right:3rem !important;margin-left:3rem !important}.my-xs-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xs-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 20rem){.m-xs-9{margin:3.5rem !important}.mt-xs-9{margin-top:3.5rem !important}.mr-xs-9{margin-right:3.5rem !important}.mb-xs-9{margin-bottom:3.5rem !important}.ml-xs-9{margin-left:3.5rem !important}.mx-xs-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xs-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xs-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 20rem){.m-xs-10{margin:4rem !important}.mt-xs-10{margin-top:4rem !important}.mr-xs-10{margin-right:4rem !important}.mb-xs-10{margin-bottom:4rem !important}.ml-xs-10{margin-left:4rem !important}.mx-xs-10{margin-right:4rem !important;margin-left:4rem !important}.my-xs-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xs-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 31.25rem){.m-sm-0{margin:0 !important}.mt-sm-0{margin-top:0 !important}.mr-sm-0{margin-right:0 !important}.mb-sm-0{margin-bottom:0 !important}.ml-sm-0{margin-left:0 !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-sm-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 31.25rem){.m-sm-1{margin:.25rem !important}.mt-sm-1{margin-top:.25rem !important}.mr-sm-1{margin-right:.25rem !important}.mb-sm-1{margin-bottom:.25rem !important}.ml-sm-1{margin-left:.25rem !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-sm-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 31.25rem){.m-sm-2{margin:.5rem !important}.mt-sm-2{margin-top:.5rem !important}.mr-sm-2{margin-right:.5rem !important}.mb-sm-2{margin-bottom:.5rem !important}.ml-sm-2{margin-left:.5rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-sm-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 31.25rem){.m-sm-3{margin:.75rem !important}.mt-sm-3{margin-top:.75rem !important}.mr-sm-3{margin-right:.75rem !important}.mb-sm-3{margin-bottom:.75rem !important}.ml-sm-3{margin-left:.75rem !important}.mx-sm-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-sm-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-sm-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 31.25rem){.m-sm-4{margin:1rem !important}.mt-sm-4{margin-top:1rem !important}.mr-sm-4{margin-right:1rem !important}.mb-sm-4{margin-bottom:1rem !important}.ml-sm-4{margin-left:1rem !important}.mx-sm-4{margin-right:1rem !important;margin-left:1rem !important}.my-sm-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-sm-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 31.25rem){.m-sm-5{margin:1.5rem !important}.mt-sm-5{margin-top:1.5rem !important}.mr-sm-5{margin-right:1.5rem !important}.mb-sm-5{margin-bottom:1.5rem !important}.ml-sm-5{margin-left:1.5rem !important}.mx-sm-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-sm-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-sm-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 31.25rem){.m-sm-6{margin:2rem !important}.mt-sm-6{margin-top:2rem !important}.mr-sm-6{margin-right:2rem !important}.mb-sm-6{margin-bottom:2rem !important}.ml-sm-6{margin-left:2rem !important}.mx-sm-6{margin-right:2rem !important;margin-left:2rem !important}.my-sm-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-sm-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 31.25rem){.m-sm-7{margin:2.5rem !important}.mt-sm-7{margin-top:2.5rem !important}.mr-sm-7{margin-right:2.5rem !important}.mb-sm-7{margin-bottom:2.5rem !important}.ml-sm-7{margin-left:2.5rem !important}.mx-sm-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-sm-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-sm-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 31.25rem){.m-sm-8{margin:3rem !important}.mt-sm-8{margin-top:3rem !important}.mr-sm-8{margin-right:3rem !important}.mb-sm-8{margin-bottom:3rem !important}.ml-sm-8{margin-left:3rem !important}.mx-sm-8{margin-right:3rem !important;margin-left:3rem !important}.my-sm-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-sm-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 31.25rem){.m-sm-9{margin:3.5rem !important}.mt-sm-9{margin-top:3.5rem !important}.mr-sm-9{margin-right:3.5rem !important}.mb-sm-9{margin-bottom:3.5rem !important}.ml-sm-9{margin-left:3.5rem !important}.mx-sm-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-sm-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-sm-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 31.25rem){.m-sm-10{margin:4rem !important}.mt-sm-10{margin-top:4rem !important}.mr-sm-10{margin-right:4rem !important}.mb-sm-10{margin-bottom:4rem !important}.ml-sm-10{margin-left:4rem !important}.mx-sm-10{margin-right:4rem !important;margin-left:4rem !important}.my-sm-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-sm-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 50rem){.m-md-0{margin:0 !important}.mt-md-0{margin-top:0 !important}.mr-md-0{margin-right:0 !important}.mb-md-0{margin-bottom:0 !important}.ml-md-0{margin-left:0 !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-md-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 50rem){.m-md-1{margin:.25rem !important}.mt-md-1{margin-top:.25rem !important}.mr-md-1{margin-right:.25rem !important}.mb-md-1{margin-bottom:.25rem !important}.ml-md-1{margin-left:.25rem !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-md-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 50rem){.m-md-2{margin:.5rem !important}.mt-md-2{margin-top:.5rem !important}.mr-md-2{margin-right:.5rem !important}.mb-md-2{margin-bottom:.5rem !important}.ml-md-2{margin-left:.5rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-md-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 50rem){.m-md-3{margin:.75rem !important}.mt-md-3{margin-top:.75rem !important}.mr-md-3{margin-right:.75rem !important}.mb-md-3{margin-bottom:.75rem !important}.ml-md-3{margin-left:.75rem !important}.mx-md-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-md-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-md-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 50rem){.m-md-4{margin:1rem !important}.mt-md-4{margin-top:1rem !important}.mr-md-4{margin-right:1rem !important}.mb-md-4{margin-bottom:1rem !important}.ml-md-4{margin-left:1rem !important}.mx-md-4{margin-right:1rem !important;margin-left:1rem !important}.my-md-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-md-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 50rem){.m-md-5{margin:1.5rem !important}.mt-md-5{margin-top:1.5rem !important}.mr-md-5{margin-right:1.5rem !important}.mb-md-5{margin-bottom:1.5rem !important}.ml-md-5{margin-left:1.5rem !important}.mx-md-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-md-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-md-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 50rem){.m-md-6{margin:2rem !important}.mt-md-6{margin-top:2rem !important}.mr-md-6{margin-right:2rem !important}.mb-md-6{margin-bottom:2rem !important}.ml-md-6{margin-left:2rem !important}.mx-md-6{margin-right:2rem !important;margin-left:2rem !important}.my-md-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-md-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 50rem){.m-md-7{margin:2.5rem !important}.mt-md-7{margin-top:2.5rem !important}.mr-md-7{margin-right:2.5rem !important}.mb-md-7{margin-bottom:2.5rem !important}.ml-md-7{margin-left:2.5rem !important}.mx-md-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-md-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-md-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 50rem){.m-md-8{margin:3rem !important}.mt-md-8{margin-top:3rem !important}.mr-md-8{margin-right:3rem !important}.mb-md-8{margin-bottom:3rem !important}.ml-md-8{margin-left:3rem !important}.mx-md-8{margin-right:3rem !important;margin-left:3rem !important}.my-md-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-md-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 50rem){.m-md-9{margin:3.5rem !important}.mt-md-9{margin-top:3.5rem !important}.mr-md-9{margin-right:3.5rem !important}.mb-md-9{margin-bottom:3.5rem !important}.ml-md-9{margin-left:3.5rem !important}.mx-md-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-md-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-md-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 50rem){.m-md-10{margin:4rem !important}.mt-md-10{margin-top:4rem !important}.mr-md-10{margin-right:4rem !important}.mb-md-10{margin-bottom:4rem !important}.ml-md-10{margin-left:4rem !important}.mx-md-10{margin-right:4rem !important;margin-left:4rem !important}.my-md-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-md-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 66.5rem){.m-lg-0{margin:0 !important}.mt-lg-0{margin-top:0 !important}.mr-lg-0{margin-right:0 !important}.mb-lg-0{margin-bottom:0 !important}.ml-lg-0{margin-left:0 !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-lg-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 66.5rem){.m-lg-1{margin:.25rem !important}.mt-lg-1{margin-top:.25rem !important}.mr-lg-1{margin-right:.25rem !important}.mb-lg-1{margin-bottom:.25rem !important}.ml-lg-1{margin-left:.25rem !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-lg-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 66.5rem){.m-lg-2{margin:.5rem !important}.mt-lg-2{margin-top:.5rem !important}.mr-lg-2{margin-right:.5rem !important}.mb-lg-2{margin-bottom:.5rem !important}.ml-lg-2{margin-left:.5rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-lg-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 66.5rem){.m-lg-3{margin:.75rem !important}.mt-lg-3{margin-top:.75rem !important}.mr-lg-3{margin-right:.75rem !important}.mb-lg-3{margin-bottom:.75rem !important}.ml-lg-3{margin-left:.75rem !important}.mx-lg-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-lg-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-lg-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 66.5rem){.m-lg-4{margin:1rem !important}.mt-lg-4{margin-top:1rem !important}.mr-lg-4{margin-right:1rem !important}.mb-lg-4{margin-bottom:1rem !important}.ml-lg-4{margin-left:1rem !important}.mx-lg-4{margin-right:1rem !important;margin-left:1rem !important}.my-lg-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-lg-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 66.5rem){.m-lg-5{margin:1.5rem !important}.mt-lg-5{margin-top:1.5rem !important}.mr-lg-5{margin-right:1.5rem !important}.mb-lg-5{margin-bottom:1.5rem !important}.ml-lg-5{margin-left:1.5rem !important}.mx-lg-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-lg-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-lg-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 66.5rem){.m-lg-6{margin:2rem !important}.mt-lg-6{margin-top:2rem !important}.mr-lg-6{margin-right:2rem !important}.mb-lg-6{margin-bottom:2rem !important}.ml-lg-6{margin-left:2rem !important}.mx-lg-6{margin-right:2rem !important;margin-left:2rem !important}.my-lg-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-lg-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 66.5rem){.m-lg-7{margin:2.5rem !important}.mt-lg-7{margin-top:2.5rem !important}.mr-lg-7{margin-right:2.5rem !important}.mb-lg-7{margin-bottom:2.5rem !important}.ml-lg-7{margin-left:2.5rem !important}.mx-lg-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-lg-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-lg-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 66.5rem){.m-lg-8{margin:3rem !important}.mt-lg-8{margin-top:3rem !important}.mr-lg-8{margin-right:3rem !important}.mb-lg-8{margin-bottom:3rem !important}.ml-lg-8{margin-left:3rem !important}.mx-lg-8{margin-right:3rem !important;margin-left:3rem !important}.my-lg-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-lg-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 66.5rem){.m-lg-9{margin:3.5rem !important}.mt-lg-9{margin-top:3.5rem !important}.mr-lg-9{margin-right:3.5rem !important}.mb-lg-9{margin-bottom:3.5rem !important}.ml-lg-9{margin-left:3.5rem !important}.mx-lg-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-lg-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-lg-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 66.5rem){.m-lg-10{margin:4rem !important}.mt-lg-10{margin-top:4rem !important}.mr-lg-10{margin-right:4rem !important}.mb-lg-10{margin-bottom:4rem !important}.ml-lg-10{margin-left:4rem !important}.mx-lg-10{margin-right:4rem !important;margin-left:4rem !important}.my-lg-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-lg-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 87.5rem){.m-xl-0{margin:0 !important}.mt-xl-0{margin-top:0 !important}.mr-xl-0{margin-right:0 !important}.mb-xl-0{margin-bottom:0 !important}.ml-xl-0{margin-left:0 !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xl-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 87.5rem){.m-xl-1{margin:.25rem !important}.mt-xl-1{margin-top:.25rem !important}.mr-xl-1{margin-right:.25rem !important}.mb-xl-1{margin-bottom:.25rem !important}.ml-xl-1{margin-left:.25rem !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xl-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 87.5rem){.m-xl-2{margin:.5rem !important}.mt-xl-2{margin-top:.5rem !important}.mr-xl-2{margin-right:.5rem !important}.mb-xl-2{margin-bottom:.5rem !important}.ml-xl-2{margin-left:.5rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xl-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 87.5rem){.m-xl-3{margin:.75rem !important}.mt-xl-3{margin-top:.75rem !important}.mr-xl-3{margin-right:.75rem !important}.mb-xl-3{margin-bottom:.75rem !important}.ml-xl-3{margin-left:.75rem !important}.mx-xl-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xl-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xl-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 87.5rem){.m-xl-4{margin:1rem !important}.mt-xl-4{margin-top:1rem !important}.mr-xl-4{margin-right:1rem !important}.mb-xl-4{margin-bottom:1rem !important}.ml-xl-4{margin-left:1rem !important}.mx-xl-4{margin-right:1rem !important;margin-left:1rem !important}.my-xl-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xl-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 87.5rem){.m-xl-5{margin:1.5rem !important}.mt-xl-5{margin-top:1.5rem !important}.mr-xl-5{margin-right:1.5rem !important}.mb-xl-5{margin-bottom:1.5rem !important}.ml-xl-5{margin-left:1.5rem !important}.mx-xl-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xl-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xl-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 87.5rem){.m-xl-6{margin:2rem !important}.mt-xl-6{margin-top:2rem !important}.mr-xl-6{margin-right:2rem !important}.mb-xl-6{margin-bottom:2rem !important}.ml-xl-6{margin-left:2rem !important}.mx-xl-6{margin-right:2rem !important;margin-left:2rem !important}.my-xl-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xl-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 87.5rem){.m-xl-7{margin:2.5rem !important}.mt-xl-7{margin-top:2.5rem !important}.mr-xl-7{margin-right:2.5rem !important}.mb-xl-7{margin-bottom:2.5rem !important}.ml-xl-7{margin-left:2.5rem !important}.mx-xl-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xl-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xl-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 87.5rem){.m-xl-8{margin:3rem !important}.mt-xl-8{margin-top:3rem !important}.mr-xl-8{margin-right:3rem !important}.mb-xl-8{margin-bottom:3rem !important}.ml-xl-8{margin-left:3rem !important}.mx-xl-8{margin-right:3rem !important;margin-left:3rem !important}.my-xl-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xl-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 87.5rem){.m-xl-9{margin:3.5rem !important}.mt-xl-9{margin-top:3.5rem !important}.mr-xl-9{margin-right:3.5rem !important}.mb-xl-9{margin-bottom:3.5rem !important}.ml-xl-9{margin-left:3.5rem !important}.mx-xl-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xl-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xl-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 87.5rem){.m-xl-10{margin:4rem !important}.mt-xl-10{margin-top:4rem !important}.mr-xl-10{margin-right:4rem !important}.mb-xl-10{margin-bottom:4rem !important}.ml-xl-10{margin-left:4rem !important}.mx-xl-10{margin-right:4rem !important;margin-left:4rem !important}.my-xl-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xl-10{margin-right:-4rem !important;margin-left:-4rem !important}}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-right:0 !important;padding-left:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-right:1rem !important;padding-left:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:2rem !important}.pt-6{padding-top:2rem !important}.pr-6{padding-right:2rem !important}.pb-6{padding-bottom:2rem !important}.pl-6{padding-left:2rem !important}.px-6{padding-right:2rem !important;padding-left:2rem !important}.py-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-7{padding:2.5rem !important}.pt-7{padding-top:2.5rem !important}.pr-7{padding-right:2.5rem !important}.pb-7{padding-bottom:2.5rem !important}.pl-7{padding-left:2.5rem !important}.px-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-8{padding:3rem !important}.pt-8{padding-top:3rem !important}.pr-8{padding-right:3rem !important}.pb-8{padding-bottom:3rem !important}.pl-8{padding-left:3rem !important}.px-8{padding-right:3rem !important;padding-left:3rem !important}.py-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-9{padding:3.5rem !important}.pt-9{padding-top:3.5rem !important}.pr-9{padding-right:3.5rem !important}.pb-9{padding-bottom:3.5rem !important}.pl-9{padding-left:3.5rem !important}.px-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-10{padding:4rem !important}.pt-10{padding-top:4rem !important}.pr-10{padding-right:4rem !important}.pb-10{padding-bottom:4rem !important}.pl-10{padding-left:4rem !important}.px-10{padding-right:4rem !important;padding-left:4rem !important}.py-10{padding-top:4rem !important;padding-bottom:4rem !important}@media (min-width: 20rem){.p-xs-0{padding:0 !important}.pt-xs-0{padding-top:0 !important}.pr-xs-0{padding-right:0 !important}.pb-xs-0{padding-bottom:0 !important}.pl-xs-0{padding-left:0 !important}.px-xs-0{padding-right:0 !important;padding-left:0 !important}.py-xs-0{padding-top:0 !important;padding-bottom:0 !important}.p-xs-1{padding:.25rem !important}.pt-xs-1{padding-top:.25rem !important}.pr-xs-1{padding-right:.25rem !important}.pb-xs-1{padding-bottom:.25rem !important}.pl-xs-1{padding-left:.25rem !important}.px-xs-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xs-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xs-2{padding:.5rem !important}.pt-xs-2{padding-top:.5rem !important}.pr-xs-2{padding-right:.5rem !important}.pb-xs-2{padding-bottom:.5rem !important}.pl-xs-2{padding-left:.5rem !important}.px-xs-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xs-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xs-3{padding:.75rem !important}.pt-xs-3{padding-top:.75rem !important}.pr-xs-3{padding-right:.75rem !important}.pb-xs-3{padding-bottom:.75rem !important}.pl-xs-3{padding-left:.75rem !important}.px-xs-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xs-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xs-4{padding:1rem !important}.pt-xs-4{padding-top:1rem !important}.pr-xs-4{padding-right:1rem !important}.pb-xs-4{padding-bottom:1rem !important}.pl-xs-4{padding-left:1rem !important}.px-xs-4{padding-right:1rem !important;padding-left:1rem !important}.py-xs-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xs-5{padding:1.5rem !important}.pt-xs-5{padding-top:1.5rem !important}.pr-xs-5{padding-right:1.5rem !important}.pb-xs-5{padding-bottom:1.5rem !important}.pl-xs-5{padding-left:1.5rem !important}.px-xs-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xs-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xs-6{padding:2rem !important}.pt-xs-6{padding-top:2rem !important}.pr-xs-6{padding-right:2rem !important}.pb-xs-6{padding-bottom:2rem !important}.pl-xs-6{padding-left:2rem !important}.px-xs-6{padding-right:2rem !important;padding-left:2rem !important}.py-xs-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xs-7{padding:2.5rem !important}.pt-xs-7{padding-top:2.5rem !important}.pr-xs-7{padding-right:2.5rem !important}.pb-xs-7{padding-bottom:2.5rem !important}.pl-xs-7{padding-left:2.5rem !important}.px-xs-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xs-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xs-8{padding:3rem !important}.pt-xs-8{padding-top:3rem !important}.pr-xs-8{padding-right:3rem !important}.pb-xs-8{padding-bottom:3rem !important}.pl-xs-8{padding-left:3rem !important}.px-xs-8{padding-right:3rem !important;padding-left:3rem !important}.py-xs-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xs-9{padding:3.5rem !important}.pt-xs-9{padding-top:3.5rem !important}.pr-xs-9{padding-right:3.5rem !important}.pb-xs-9{padding-bottom:3.5rem !important}.pl-xs-9{padding-left:3.5rem !important}.px-xs-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xs-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xs-10{padding:4rem !important}.pt-xs-10{padding-top:4rem !important}.pr-xs-10{padding-right:4rem !important}.pb-xs-10{padding-bottom:4rem !important}.pl-xs-10{padding-left:4rem !important}.px-xs-10{padding-right:4rem !important;padding-left:4rem !important}.py-xs-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 31.25rem){.p-sm-0{padding:0 !important}.pt-sm-0{padding-top:0 !important}.pr-sm-0{padding-right:0 !important}.pb-sm-0{padding-bottom:0 !important}.pl-sm-0{padding-left:0 !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1{padding-top:.25rem !important}.pr-sm-1{padding-right:.25rem !important}.pb-sm-1{padding-bottom:.25rem !important}.pl-sm-1{padding-left:.25rem !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2{padding-top:.5rem !important}.pr-sm-2{padding-right:.5rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pl-sm-2{padding-left:.5rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-sm-3{padding:.75rem !important}.pt-sm-3{padding-top:.75rem !important}.pr-sm-3{padding-right:.75rem !important}.pb-sm-3{padding-bottom:.75rem !important}.pl-sm-3{padding-left:.75rem !important}.px-sm-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-sm-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-sm-4{padding:1rem !important}.pt-sm-4{padding-top:1rem !important}.pr-sm-4{padding-right:1rem !important}.pb-sm-4{padding-bottom:1rem !important}.pl-sm-4{padding-left:1rem !important}.px-sm-4{padding-right:1rem !important;padding-left:1rem !important}.py-sm-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-sm-5{padding:1.5rem !important}.pt-sm-5{padding-top:1.5rem !important}.pr-sm-5{padding-right:1.5rem !important}.pb-sm-5{padding-bottom:1.5rem !important}.pl-sm-5{padding-left:1.5rem !important}.px-sm-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-sm-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-sm-6{padding:2rem !important}.pt-sm-6{padding-top:2rem !important}.pr-sm-6{padding-right:2rem !important}.pb-sm-6{padding-bottom:2rem !important}.pl-sm-6{padding-left:2rem !important}.px-sm-6{padding-right:2rem !important;padding-left:2rem !important}.py-sm-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-sm-7{padding:2.5rem !important}.pt-sm-7{padding-top:2.5rem !important}.pr-sm-7{padding-right:2.5rem !important}.pb-sm-7{padding-bottom:2.5rem !important}.pl-sm-7{padding-left:2.5rem !important}.px-sm-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-sm-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-sm-8{padding:3rem !important}.pt-sm-8{padding-top:3rem !important}.pr-sm-8{padding-right:3rem !important}.pb-sm-8{padding-bottom:3rem !important}.pl-sm-8{padding-left:3rem !important}.px-sm-8{padding-right:3rem !important;padding-left:3rem !important}.py-sm-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-sm-9{padding:3.5rem !important}.pt-sm-9{padding-top:3.5rem !important}.pr-sm-9{padding-right:3.5rem !important}.pb-sm-9{padding-bottom:3.5rem !important}.pl-sm-9{padding-left:3.5rem !important}.px-sm-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-sm-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-sm-10{padding:4rem !important}.pt-sm-10{padding-top:4rem !important}.pr-sm-10{padding-right:4rem !important}.pb-sm-10{padding-bottom:4rem !important}.pl-sm-10{padding-left:4rem !important}.px-sm-10{padding-right:4rem !important;padding-left:4rem !important}.py-sm-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 50rem){.p-md-0{padding:0 !important}.pt-md-0{padding-top:0 !important}.pr-md-0{padding-right:0 !important}.pb-md-0{padding-bottom:0 !important}.pl-md-0{padding-left:0 !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1{padding-top:.25rem !important}.pr-md-1{padding-right:.25rem !important}.pb-md-1{padding-bottom:.25rem !important}.pl-md-1{padding-left:.25rem !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2{padding-top:.5rem !important}.pr-md-2{padding-right:.5rem !important}.pb-md-2{padding-bottom:.5rem !important}.pl-md-2{padding-left:.5rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-md-3{padding:.75rem !important}.pt-md-3{padding-top:.75rem !important}.pr-md-3{padding-right:.75rem !important}.pb-md-3{padding-bottom:.75rem !important}.pl-md-3{padding-left:.75rem !important}.px-md-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-md-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-md-4{padding:1rem !important}.pt-md-4{padding-top:1rem !important}.pr-md-4{padding-right:1rem !important}.pb-md-4{padding-bottom:1rem !important}.pl-md-4{padding-left:1rem !important}.px-md-4{padding-right:1rem !important;padding-left:1rem !important}.py-md-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-md-5{padding:1.5rem !important}.pt-md-5{padding-top:1.5rem !important}.pr-md-5{padding-right:1.5rem !important}.pb-md-5{padding-bottom:1.5rem !important}.pl-md-5{padding-left:1.5rem !important}.px-md-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-md-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-md-6{padding:2rem !important}.pt-md-6{padding-top:2rem !important}.pr-md-6{padding-right:2rem !important}.pb-md-6{padding-bottom:2rem !important}.pl-md-6{padding-left:2rem !important}.px-md-6{padding-right:2rem !important;padding-left:2rem !important}.py-md-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-md-7{padding:2.5rem !important}.pt-md-7{padding-top:2.5rem !important}.pr-md-7{padding-right:2.5rem !important}.pb-md-7{padding-bottom:2.5rem !important}.pl-md-7{padding-left:2.5rem !important}.px-md-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-md-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-md-8{padding:3rem !important}.pt-md-8{padding-top:3rem !important}.pr-md-8{padding-right:3rem !important}.pb-md-8{padding-bottom:3rem !important}.pl-md-8{padding-left:3rem !important}.px-md-8{padding-right:3rem !important;padding-left:3rem !important}.py-md-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-md-9{padding:3.5rem !important}.pt-md-9{padding-top:3.5rem !important}.pr-md-9{padding-right:3.5rem !important}.pb-md-9{padding-bottom:3.5rem !important}.pl-md-9{padding-left:3.5rem !important}.px-md-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-md-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-md-10{padding:4rem !important}.pt-md-10{padding-top:4rem !important}.pr-md-10{padding-right:4rem !important}.pb-md-10{padding-bottom:4rem !important}.pl-md-10{padding-left:4rem !important}.px-md-10{padding-right:4rem !important;padding-left:4rem !important}.py-md-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 66.5rem){.p-lg-0{padding:0 !important}.pt-lg-0{padding-top:0 !important}.pr-lg-0{padding-right:0 !important}.pb-lg-0{padding-bottom:0 !important}.pl-lg-0{padding-left:0 !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1{padding-top:.25rem !important}.pr-lg-1{padding-right:.25rem !important}.pb-lg-1{padding-bottom:.25rem !important}.pl-lg-1{padding-left:.25rem !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2{padding-top:.5rem !important}.pr-lg-2{padding-right:.5rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pl-lg-2{padding-left:.5rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-lg-3{padding:.75rem !important}.pt-lg-3{padding-top:.75rem !important}.pr-lg-3{padding-right:.75rem !important}.pb-lg-3{padding-bottom:.75rem !important}.pl-lg-3{padding-left:.75rem !important}.px-lg-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-lg-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-lg-4{padding:1rem !important}.pt-lg-4{padding-top:1rem !important}.pr-lg-4{padding-right:1rem !important}.pb-lg-4{padding-bottom:1rem !important}.pl-lg-4{padding-left:1rem !important}.px-lg-4{padding-right:1rem !important;padding-left:1rem !important}.py-lg-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-lg-5{padding:1.5rem !important}.pt-lg-5{padding-top:1.5rem !important}.pr-lg-5{padding-right:1.5rem !important}.pb-lg-5{padding-bottom:1.5rem !important}.pl-lg-5{padding-left:1.5rem !important}.px-lg-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-lg-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-lg-6{padding:2rem !important}.pt-lg-6{padding-top:2rem !important}.pr-lg-6{padding-right:2rem !important}.pb-lg-6{padding-bottom:2rem !important}.pl-lg-6{padding-left:2rem !important}.px-lg-6{padding-right:2rem !important;padding-left:2rem !important}.py-lg-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-lg-7{padding:2.5rem !important}.pt-lg-7{padding-top:2.5rem !important}.pr-lg-7{padding-right:2.5rem !important}.pb-lg-7{padding-bottom:2.5rem !important}.pl-lg-7{padding-left:2.5rem !important}.px-lg-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-lg-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-lg-8{padding:3rem !important}.pt-lg-8{padding-top:3rem !important}.pr-lg-8{padding-right:3rem !important}.pb-lg-8{padding-bottom:3rem !important}.pl-lg-8{padding-left:3rem !important}.px-lg-8{padding-right:3rem !important;padding-left:3rem !important}.py-lg-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-lg-9{padding:3.5rem !important}.pt-lg-9{padding-top:3.5rem !important}.pr-lg-9{padding-right:3.5rem !important}.pb-lg-9{padding-bottom:3.5rem !important}.pl-lg-9{padding-left:3.5rem !important}.px-lg-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-lg-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-lg-10{padding:4rem !important}.pt-lg-10{padding-top:4rem !important}.pr-lg-10{padding-right:4rem !important}.pb-lg-10{padding-bottom:4rem !important}.pl-lg-10{padding-left:4rem !important}.px-lg-10{padding-right:4rem !important;padding-left:4rem !important}.py-lg-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 87.5rem){.p-xl-0{padding:0 !important}.pt-xl-0{padding-top:0 !important}.pr-xl-0{padding-right:0 !important}.pb-xl-0{padding-bottom:0 !important}.pl-xl-0{padding-left:0 !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1{padding-top:.25rem !important}.pr-xl-1{padding-right:.25rem !important}.pb-xl-1{padding-bottom:.25rem !important}.pl-xl-1{padding-left:.25rem !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2{padding-top:.5rem !important}.pr-xl-2{padding-right:.5rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pl-xl-2{padding-left:.5rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xl-3{padding:.75rem !important}.pt-xl-3{padding-top:.75rem !important}.pr-xl-3{padding-right:.75rem !important}.pb-xl-3{padding-bottom:.75rem !important}.pl-xl-3{padding-left:.75rem !important}.px-xl-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xl-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xl-4{padding:1rem !important}.pt-xl-4{padding-top:1rem !important}.pr-xl-4{padding-right:1rem !important}.pb-xl-4{padding-bottom:1rem !important}.pl-xl-4{padding-left:1rem !important}.px-xl-4{padding-right:1rem !important;padding-left:1rem !important}.py-xl-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xl-5{padding:1.5rem !important}.pt-xl-5{padding-top:1.5rem !important}.pr-xl-5{padding-right:1.5rem !important}.pb-xl-5{padding-bottom:1.5rem !important}.pl-xl-5{padding-left:1.5rem !important}.px-xl-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xl-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xl-6{padding:2rem !important}.pt-xl-6{padding-top:2rem !important}.pr-xl-6{padding-right:2rem !important}.pb-xl-6{padding-bottom:2rem !important}.pl-xl-6{padding-left:2rem !important}.px-xl-6{padding-right:2rem !important;padding-left:2rem !important}.py-xl-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xl-7{padding:2.5rem !important}.pt-xl-7{padding-top:2.5rem !important}.pr-xl-7{padding-right:2.5rem !important}.pb-xl-7{padding-bottom:2.5rem !important}.pl-xl-7{padding-left:2.5rem !important}.px-xl-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xl-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xl-8{padding:3rem !important}.pt-xl-8{padding-top:3rem !important}.pr-xl-8{padding-right:3rem !important}.pb-xl-8{padding-bottom:3rem !important}.pl-xl-8{padding-left:3rem !important}.px-xl-8{padding-right:3rem !important;padding-left:3rem !important}.py-xl-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xl-9{padding:3.5rem !important}.pt-xl-9{padding-top:3.5rem !important}.pr-xl-9{padding-right:3.5rem !important}.pb-xl-9{padding-bottom:3.5rem !important}.pl-xl-9{padding-left:3.5rem !important}.px-xl-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xl-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xl-10{padding:4rem !important}.pt-xl-10{padding-top:4rem !important}.pr-xl-10{padding-right:4rem !important}.pb-xl-10{padding-bottom:4rem !important}.pl-xl-10{padding-left:4rem !important}.px-xl-10{padding-right:4rem !important;padding-left:4rem !important}.py-xl-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media print{.site-footer,.site-button,#edit-this-page,#back-to-top,.site-nav,.main-header{display:none !important}.side-bar{width:100%;height:auto;border-right:0 !important}.site-header{border-bottom:1px solid #44434d}.site-title{font-size:16px !important;font-weight:700 !important}.text-small{font-size:8pt !important}pre.highlight{border:1px solid #44434d}.main{max-width:none;margin-left:0}}a.skip-to-main{left:-999px;position:absolute;top:auto;width:1px;height:1px;overflow:hidden;z-index:-999}a.skip-to-main:focus,a.skip-to-main:active{color:#2c84fa;background-color:#27262b;left:auto;top:auto;width:30%;height:auto;overflow:auto;margin:10px 35%;padding:5px;border-radius:15px;border:4px solid #264caf;text-align:center;font-size:1.2em;z-index:999}div.opaque{background-color:#27262b} diff --git a/assets/css/just-the-docs-default.css b/assets/css/just-the-docs-default.css new file mode 100644 index 0000000000..96c47a3a02 --- /dev/null +++ b/assets/css/just-the-docs-default.css @@ -0,0 +1 @@ +.highlight .c{color:#586e75}.highlight .err{color:#93a1a1}.highlight .g{color:#93a1a1}.highlight .k{color:#859900}.highlight .l{color:#93a1a1}.highlight .n{color:#93a1a1}.highlight .o{color:#859900}.highlight .x{color:#cb4b16}.highlight .p{color:#93a1a1}.highlight .cm{color:#586e75}.highlight .cp{color:#859900}.highlight .c1{color:#586e75}.highlight .cs{color:#859900}.highlight .gd{color:#2aa198}.highlight .ge{font-style:italic;color:#93a1a1}.highlight .gr{color:#dc322f}.highlight .gh{color:#cb4b16}.highlight .gi{color:#859900}.highlight .go{color:#93a1a1}.highlight .gp{color:#93a1a1}.highlight .gs{font-weight:bold;color:#93a1a1}.highlight .gu{color:#cb4b16}.highlight .gt{color:#93a1a1}.highlight .kc{color:#cb4b16}.highlight .kd{color:#268bd2}.highlight .kn{color:#859900}.highlight .kp{color:#859900}.highlight .kr{color:#268bd2}.highlight .kt{color:#dc322f}.highlight .ld{color:#93a1a1}.highlight .m{color:#2aa198}.highlight .s{color:#2aa198}.highlight .na{color:#555}.highlight .nb{color:#b58900}.highlight .nc{color:#268bd2}.highlight .no{color:#cb4b16}.highlight .nd{color:#268bd2}.highlight .ni{color:#cb4b16}.highlight .ne{color:#cb4b16}.highlight .nf{color:#268bd2}.highlight .nl{color:#555}.highlight .nn{color:#93a1a1}.highlight .nx{color:#555}.highlight .py{color:#93a1a1}.highlight .nt{color:#268bd2}.highlight .nv{color:#268bd2}.highlight .ow{color:#859900}.highlight .w{color:#93a1a1}.highlight .mf{color:#2aa198}.highlight .mh{color:#2aa198}.highlight .mi{color:#2aa198}.highlight .mo{color:#2aa198}.highlight .sb{color:#586e75}.highlight .sc{color:#2aa198}.highlight .sd{color:#93a1a1}.highlight .s2{color:#2aa198}.highlight .se{color:#cb4b16}.highlight .sh{color:#93a1a1}.highlight .si{color:#2aa198}.highlight .sx{color:#2aa198}.highlight .sr{color:#dc322f}.highlight .s1{color:#2aa198}.highlight .ss{color:#2aa198}.highlight .bp{color:#268bd2}.highlight .vc{color:#268bd2}.highlight .vg{color:#268bd2}.highlight .vi{color:#268bd2}.highlight .il{color:#2aa198}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*{box-sizing:border-box}::selection{color:#fff;background:#53a3da}html{font-size:14px !important;scroll-behavior:smooth}@media (min-width: 31.25rem){html{font-size:16px !important}}body{font-family:system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;font-size:inherit;line-height:1.4;color:#5c5962;background-color:#fff;overflow-wrap:break-word}ol,ul,dl,pre,address,blockquote,table,div,hr,form,fieldset,noscript .table-wrapper{margin-top:0}h1,h2,h3,h4,h5,h6,#toctitle{margin-top:0;margin-bottom:1em;font-weight:500;line-height:1.25;color:#27262b}p{margin-top:1em;margin-bottom:1em}a{color:#53a3da;text-decoration:none}a:not([class]){text-decoration:underline;text-decoration-color:#eeebee;text-underline-offset:2px}a:not([class]):hover{text-decoration-color:rgba(83,163,218,0.45)}code{font-family:"SFMono-Regular",menlo,consolas,monospace;font-size:0.75em;line-height:1.4}figure,pre{margin:0}li{margin:0.25em 0}img{max-width:100%;height:auto}hr{height:1px;padding:0;margin:2rem 0;background-color:#eeebee;border:0}blockquote{margin:10px 0;margin-block-start:0;margin-inline-start:0;padding-left:15px;border-left:3px solid #eeebee}.side-bar{z-index:0;display:flex;flex-wrap:wrap;background-color:#f5f6fa}@media (min-width: 50rem){.side-bar{flex-flow:column nowrap;position:fixed;width:248px;height:100%;border-right:1px solid #eeebee;align-items:flex-end}}@media (min-width: 66.5rem){.side-bar{width:calc((100% - 1064px) / 2 + 264px);min-width:264px}}@media (min-width: 50rem){.main{position:relative;max-width:800px;margin-left:248px}}@media (min-width: 66.5rem){.main{margin-left:Max(264px, calc((100% - 1064px) / 2 + 264px))}}.main-content-wrap{padding-right:1rem;padding-left:1rem;padding-top:1rem;padding-bottom:1rem}@media (min-width: 50rem){.main-content-wrap{padding-right:2rem;padding-left:2rem}}@media (min-width: 50rem){.main-content-wrap{padding-top:2rem;padding-bottom:2rem}}.main-header{z-index:0;display:none;background-color:#f5f6fa}@media (min-width: 50rem){.main-header{display:flex;justify-content:space-between;height:60px;background-color:#fff;border-bottom:1px solid #eeebee}}.main-header.nav-open{display:block}@media (min-width: 50rem){.main-header.nav-open{display:flex}}.site-nav,.site-header,.site-footer{width:100%}@media (min-width: 66.5rem){.site-nav,.site-header,.site-footer{width:264px}}.site-nav{display:none}.site-nav.nav-open{display:block}@media (min-width: 50rem){.site-nav{display:block;padding-top:3rem;padding-bottom:1rem;overflow-y:auto;flex:1 1 auto}}.site-header{display:flex;min-height:60px;align-items:center}@media (min-width: 50rem){.site-header{height:60px;max-height:60px;border-bottom:1px solid #eeebee}}.site-title{padding-right:1rem;padding-left:1rem;flex-grow:1;display:flex;height:100%;align-items:center;padding-top:.75rem;padding-bottom:.75rem;color:#27262b;font-size:18px !important}@media (min-width: 50rem){.site-title{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-title{font-size:24px !important;line-height:1.25}}@media (min-width: 50rem){.site-title{padding-top:.5rem;padding-bottom:.5rem}}.site-button{display:flex;height:100%;padding:1rem;align-items:center}@media (min-width: 50rem){.site-header .site-button{display:none}}.site-title:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 80%, rgba(235,237,245,0) 100%)}.site-button:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 100%)}body{position:relative;padding-bottom:4rem;overflow-y:scroll}@media (min-width: 50rem){body{position:static;padding-bottom:0}}.site-footer{padding-right:1rem;padding-left:1rem;position:absolute;bottom:0;left:0;padding-top:1rem;padding-bottom:1rem;color:#959396;font-size:11px !important}@media (min-width: 50rem){.site-footer{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-footer{font-size:12px !important}}@media (min-width: 50rem){.site-footer{position:static;justify-self:end}}.icon{width:1.5rem;height:1.5rem;color:#53a3da}.main-content{line-height:1.6}.main-content ol,.main-content ul,.main-content dl,.main-content pre,.main-content address,.main-content blockquote,.main-content .table-wrapper{margin-top:0.5em}.main-content a{overflow:hidden;text-overflow:ellipsis}.main-content ul,.main-content ol{padding-left:1.5em}.main-content li .highlight{margin-top:.25rem}.main-content ol{list-style-type:none;counter-reset:step-counter}.main-content ol>li{position:relative}.main-content ol>li::before{position:absolute;top:0.2em;left:-1.6em;color:#959396;content:counter(step-counter);counter-increment:step-counter;font-size:12px !important}@media (min-width: 31.25rem){.main-content ol>li::before{font-size:14px !important}}@media (min-width: 31.25rem){.main-content ol>li::before{top:0.11em}}.main-content ol>li ol{counter-reset:sub-counter}.main-content ol>li ol>li::before{content:counter(sub-counter,lower-alpha);counter-increment:sub-counter}.main-content ul{list-style:none}.main-content ul>li::before{position:absolute;margin-left:-1.4em;color:#959396;content:"•"}.main-content .task-list-item::before{content:""}.main-content .task-list-item-checkbox{margin-right:0.6em;margin-left:-1.4em}.main-content hr+*{margin-top:0}.main-content h1:first-of-type{margin-top:0.5em}.main-content dl{display:grid;grid-template:auto / 10em 1fr}.main-content dt,.main-content dd{margin:0.25em 0}.main-content dt{grid-column:1;font-weight:500;text-align:right}.main-content dt::after{content:":"}.main-content dd{grid-column:2;margin-bottom:0;margin-left:1em}.main-content dd blockquote:first-child,.main-content dd div:first-child,.main-content dd dl:first-child,.main-content dd dt:first-child,.main-content dd h1:first-child,.main-content dd h2:first-child,.main-content dd h3:first-child,.main-content dd h4:first-child,.main-content dd h5:first-child,.main-content dd h6:first-child,.main-content dd li:first-child,.main-content dd ol:first-child,.main-content dd p:first-child,.main-content dd pre:first-child,.main-content dd table:first-child,.main-content dd ul:first-child,.main-content dd .table-wrapper:first-child{margin-top:0}.main-content dd dl:first-child dt:first-child,.main-content dd dl:first-child dd:nth-child(2),.main-content ol dl:first-child dt:first-child,.main-content ol dl:first-child dd:nth-child(2),.main-content ul dl:first-child dt:first-child,.main-content ul dl:first-child dd:nth-child(2){margin-top:0}.main-content .anchor-heading{position:absolute;right:-1rem;width:1.5rem;height:100%;padding-right:.25rem;padding-left:.25rem;overflow:visible}@media (min-width: 50rem){.main-content .anchor-heading{right:auto;left:-1.5rem}}.main-content .anchor-heading svg{display:inline-block;width:100%;height:100%;color:#53a3da;visibility:hidden}.main-content .anchor-heading:hover svg,.main-content .anchor-heading:focus svg,.main-content h1:hover>.anchor-heading svg,.main-content h2:hover>.anchor-heading svg,.main-content h3:hover>.anchor-heading svg,.main-content h4:hover>.anchor-heading svg,.main-content h5:hover>.anchor-heading svg,.main-content h6:hover>.anchor-heading svg{visibility:visible}.main-content summary{cursor:pointer}.main-content h1,.main-content h2,.main-content h3,.main-content h4,.main-content h5,.main-content h6,.main-content #toctitle{position:relative;margin-top:1.5em;margin-bottom:0.25em}.main-content h1+table,.main-content h1+.table-wrapper,.main-content h1+.code-example,.main-content h1+.highlighter-rouge,.main-content h1+.sectionbody .listingblock,.main-content h2+table,.main-content h2+.table-wrapper,.main-content h2+.code-example,.main-content h2+.highlighter-rouge,.main-content h2+.sectionbody .listingblock,.main-content h3+table,.main-content h3+.table-wrapper,.main-content h3+.code-example,.main-content h3+.highlighter-rouge,.main-content h3+.sectionbody .listingblock,.main-content h4+table,.main-content h4+.table-wrapper,.main-content h4+.code-example,.main-content h4+.highlighter-rouge,.main-content h4+.sectionbody .listingblock,.main-content h5+table,.main-content h5+.table-wrapper,.main-content h5+.code-example,.main-content h5+.highlighter-rouge,.main-content h5+.sectionbody .listingblock,.main-content h6+table,.main-content h6+.table-wrapper,.main-content h6+.code-example,.main-content h6+.highlighter-rouge,.main-content h6+.sectionbody .listingblock,.main-content #toctitle+table,.main-content #toctitle+.table-wrapper,.main-content #toctitle+.code-example,.main-content #toctitle+.highlighter-rouge,.main-content #toctitle+.sectionbody .listingblock{margin-top:1em}.main-content h1+p:not(.label),.main-content h2+p:not(.label),.main-content h3+p:not(.label),.main-content h4+p:not(.label),.main-content h5+p:not(.label),.main-content h6+p:not(.label),.main-content #toctitle+p:not(.label){margin-top:0}.main-content>h1:first-child,.main-content>h2:first-child,.main-content>h3:first-child,.main-content>h4:first-child,.main-content>h5:first-child,.main-content>h6:first-child,.main-content>.sect1:first-child>h2,.main-content>.sect2:first-child>h3,.main-content>.sect3:first-child>h4,.main-content>.sect4:first-child>h5,.main-content>.sect5:first-child>h6{margin-top:.5rem}.nav-list{padding:0;margin-top:0;margin-bottom:0;list-style:none}.nav-list .nav-list-item{font-size:14px !important;position:relative;margin:0}@media (min-width: 31.25rem){.nav-list .nav-list-item{font-size:16px !important}}@media (min-width: 50rem){.nav-list .nav-list-item{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.nav-list .nav-list-item{font-size:14px !important}}.nav-list .nav-list-item .nav-list-link{display:block;min-height:3rem;padding-top:.25rem;padding-bottom:.25rem;line-height:2.5rem;padding-right:3rem;padding-left:1rem}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-link{min-height:2rem;line-height:1.5rem;padding-right:2rem;padding-left:2rem}}.nav-list .nav-list-item .nav-list-link.external>svg{width:1rem;height:1rem;vertical-align:text-bottom}.nav-list .nav-list-item .nav-list-link.active{font-weight:600;text-decoration:none}.nav-list .nav-list-item .nav-list-link:hover,.nav-list .nav-list-item .nav-list-link.active{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 80%, rgba(235,237,245,0) 100%)}.nav-list .nav-list-item .nav-list-expander{position:absolute;right:0;width:3rem;height:3rem;padding:.75rem;color:#53a3da}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-expander{width:2rem;height:2rem;padding:.5rem}}.nav-list .nav-list-item .nav-list-expander:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 100%)}.nav-list .nav-list-item .nav-list-expander svg{transform:rotate(90deg)}.nav-list .nav-list-item>.nav-list{display:none;padding-left:.75rem;list-style:none}.nav-list .nav-list-item>.nav-list .nav-list-item{position:relative}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-link{color:#5c5962}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-expander{color:#5c5962}.nav-list .nav-list-item.active>.nav-list-expander svg{transform:rotate(-90deg)}.nav-list .nav-list-item.active>.nav-list{display:block}.nav-category{padding:.5rem 1rem;font-weight:600;text-align:start;text-transform:uppercase;border-bottom:1px solid #eeebee;font-size:11px !important}@media (min-width: 31.25rem){.nav-category{font-size:12px !important}}@media (min-width: 50rem){.nav-category{padding:.5rem 2rem;margin-top:1rem;text-align:start}.nav-category:first-child{margin-top:0}}.nav-list.nav-category-list>.nav-list-item{margin:0}.nav-list.nav-category-list>.nav-list-item>.nav-list{padding:0}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-link{color:#53a3da}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-expander{color:#53a3da}.aux-nav{height:100%;overflow-x:auto;font-size:11px !important}@media (min-width: 31.25rem){.aux-nav{font-size:12px !important}}.aux-nav .aux-nav-list{display:flex;height:100%;padding:0;margin:0;list-style:none}.aux-nav .aux-nav-list-item{display:inline-block;height:100%;padding:0;margin:0}@media (min-width: 50rem){.aux-nav{padding-right:1rem}}@media (min-width: 50rem){.breadcrumb-nav{margin-top:-1rem}}.breadcrumb-nav-list{padding-left:0;margin-bottom:.75rem;list-style:none}.breadcrumb-nav-list-item{display:table-cell;font-size:11px !important}@media (min-width: 31.25rem){.breadcrumb-nav-list-item{font-size:12px !important}}.breadcrumb-nav-list-item::before{display:none}.breadcrumb-nav-list-item::after{display:inline-block;margin-right:.5rem;margin-left:.5rem;color:#959396;content:"/"}.breadcrumb-nav-list-item:last-child::after{content:""}h1,.text-alpha{font-size:32px !important;line-height:1.25;font-weight:300}@media (min-width: 31.25rem){h1,.text-alpha{font-size:36px !important}}h2,.text-beta,#toctitle{font-size:18px !important}@media (min-width: 31.25rem){h2,.text-beta,#toctitle{font-size:24px !important;line-height:1.25}}h3,.text-gamma{font-size:16px !important}@media (min-width: 31.25rem){h3,.text-gamma{font-size:18px !important}}h4,.text-delta{font-size:11px !important;font-weight:400;text-transform:uppercase;letter-spacing:0.1em}@media (min-width: 31.25rem){h4,.text-delta{font-size:12px !important}}h4 code{text-transform:none}h5,.text-epsilon{font-size:12px !important}@media (min-width: 31.25rem){h5,.text-epsilon{font-size:14px !important}}h6,.text-zeta{font-size:11px !important}@media (min-width: 31.25rem){h6,.text-zeta{font-size:12px !important}}.text-small{font-size:11px !important}@media (min-width: 31.25rem){.text-small{font-size:12px !important}}.text-mono{font-family:"SFMono-Regular",menlo,consolas,monospace !important}.text-left{text-align:left !important}.text-center{text-align:center !important}.text-right{text-align:right !important}.label,.label-blue{display:inline-block;padding:0.16em 0.56em;margin-right:.5rem;margin-left:.5rem;color:#fff;text-transform:uppercase;vertical-align:middle;background-color:#2869e6;font-size:11px !important;border-radius:12px}@media (min-width: 31.25rem){.label,.label-blue{font-size:12px !important}}.label-green{background-color:#009c7b}.label-purple{background-color:#5e41d0}.label-red{background-color:#e94c4c}.label-yellow{color:#44434d;background-color:#f7d12e}.btn{display:inline-block;box-sizing:border-box;padding:0.3em 1em;margin:0;font-family:inherit;font-size:inherit;font-weight:500;line-height:1.5;color:#53a3da;text-decoration:none;vertical-align:baseline;cursor:pointer;background-color:#f7f7f7;border-width:0;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);appearance:none}.btn:focus{text-decoration:none;outline:none;box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:focus:hover,.btn.selected:focus{box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:hover,.btn.zeroclipboard-is-hover{color:#4b9fd8}.btn:hover,.btn:active,.btn.zeroclipboard-is-hover,.btn.zeroclipboard-is-active{text-decoration:none;background-color:#f4f4f4}.btn:active,.btn.selected,.btn.zeroclipboard-is-active{background-color:#efefef;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn.selected:hover{background-color:#cfcfcf}.btn:disabled,.btn:disabled:hover,.btn.disabled,.btn.disabled:hover{color:rgba(102,102,102,0.5);cursor:default;background-color:rgba(229,229,229,0.5);background-image:none;box-shadow:none}.btn-outline{color:#53a3da;background:transparent;box-shadow:inset 0 0 0 2px #e6e1e8}.btn-outline:hover,.btn-outline:active,.btn-outline.zeroclipboard-is-hover,.btn-outline.zeroclipboard-is-active{color:#429ad6;text-decoration:none;background-color:transparent;box-shadow:inset 0 0 0 3px #e6e1e8}.btn-outline:focus{text-decoration:none;outline:none;box-shadow:inset 0 0 0 2px #5c5962,0 0 0 3px rgba(0,0,255,0.25)}.btn-outline:focus:hover,.btn-outline.selected:focus{box-shadow:inset 0 0 0 2px #5c5962}.btn-primary{color:#fff;background-color:#5739ce;background-image:linear-gradient(#6f55d5, #5739ce);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-primary:hover,.btn-primary.zeroclipboard-is-hover{color:#fff;background-color:#5132cb;background-image:linear-gradient(#6549d2,#5132cb)}.btn-primary:active,.btn-primary.selected,.btn-primary.zeroclipboard-is-active{background-color:#4f31c6;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-primary.selected:hover{background-color:#472cb2}.btn-purple{color:#fff;background-color:#5739ce;background-image:linear-gradient(#6f55d5, #5739ce);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-purple:hover,.btn-purple.zeroclipboard-is-hover{color:#fff;background-color:#5132cb;background-image:linear-gradient(#6549d2,#5132cb)}.btn-purple:active,.btn-purple.selected,.btn-purple.zeroclipboard-is-active{background-color:#4f31c6;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-purple.selected:hover{background-color:#472cb2}.btn-blue{color:#fff;background-color:#227efa;background-image:linear-gradient(#4593fb, #227efa);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-blue:hover,.btn-blue.zeroclipboard-is-hover{color:#fff;background-color:#1878fa;background-image:linear-gradient(#368afa,#1878fa)}.btn-blue:active,.btn-blue.selected,.btn-blue.zeroclipboard-is-active{background-color:#1375f9;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-blue.selected:hover{background-color:#0669ed}.btn-green{color:#fff;background-color:#10ac7d;background-image:linear-gradient(#13cc95, #10ac7d);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-green:hover,.btn-green.zeroclipboard-is-hover{color:#fff;background-color:#0fa276;background-image:linear-gradient(#12be8b,#0fa276)}.btn-green:active,.btn-green.selected,.btn-green.zeroclipboard-is-active{background-color:#0f9e73;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-green.selected:hover{background-color:#0d8662}.search{position:relative;z-index:2;flex-grow:1;height:4rem;padding:.5rem;transition:padding linear 200ms}@media (min-width: 50rem){.search{position:relative !important;width:auto !important;height:100% !important;padding:0;transition:none}}.search-input-wrap{position:relative;z-index:1;height:3rem;overflow:hidden;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);transition:height linear 200ms}@media (min-width: 50rem){.search-input-wrap{position:absolute;width:100%;max-width:536px;height:100% !important;border-radius:0;box-shadow:none;transition:width ease 400ms}}.search-input{position:absolute;width:100%;height:100%;padding:.5rem 1rem .5rem 2.5rem;font-size:16px;color:#5c5962;background-color:#fff;border-top:0;border-right:0;border-bottom:0;border-left:0;border-radius:0}@media (min-width: 50rem){.search-input{padding:.5rem 1rem .5rem 3.5rem;font-size:14px;background-color:#fff;transition:padding-left linear 200ms}}.search-input:focus{outline:0}.search-input:focus+.search-label .search-icon{color:#53a3da}.search-label{position:absolute;display:flex;height:100%;padding-left:1rem}@media (min-width: 50rem){.search-label{padding-left:2rem;transition:padding-left linear 200ms}}.search-label .search-icon{width:1.2rem;height:1.2rem;align-self:center;color:#959396}.search-results{position:absolute;left:0;display:none;width:100%;max-height:calc(100% - 4rem);overflow-y:auto;background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}@media (min-width: 50rem){.search-results{top:100%;width:536px;max-height:calc(100vh - 200%) !important}}.search-results-list{padding-left:0;margin-bottom:.25rem;list-style:none;font-size:14px !important}@media (min-width: 31.25rem){.search-results-list{font-size:16px !important}}@media (min-width: 50rem){.search-results-list{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-results-list{font-size:14px !important}}.search-results-list-item{padding:0;margin:0}.search-result{display:block;padding:.25rem .75rem}.search-result:hover,.search-result.active{background-color:#ebedf5}.search-result-title{display:block;padding-top:.5rem;padding-bottom:.5rem}@media (min-width: 31.25rem){.search-result-title{display:inline-block;width:40%;padding-right:.5rem;vertical-align:top}}.search-result-doc{display:flex;align-items:center;word-wrap:break-word}.search-result-doc.search-result-doc-parent{opacity:0.5;font-size:12px !important}@media (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:14px !important}}@media (min-width: 50rem){.search-result-doc.search-result-doc-parent{font-size:11px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:12px !important}}.search-result-doc .search-result-icon{width:1rem;height:1rem;margin-right:.5rem;color:#53a3da;flex-shrink:0}.search-result-doc .search-result-doc-title{overflow:auto}.search-result-section{margin-left:1.5rem;word-wrap:break-word}.search-result-rel-url{display:block;margin-left:1.5rem;overflow:hidden;color:#959396;text-overflow:ellipsis;white-space:nowrap;font-size:9px !important}@media (min-width: 31.25rem){.search-result-rel-url{font-size:10px !important}}.search-result-previews{display:block;padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;margin-left:.5rem;color:#959396;word-wrap:break-word;border-left:1px solid;border-left-color:#eeebee;font-size:11px !important}@media (min-width: 31.25rem){.search-result-previews{font-size:12px !important}}@media (min-width: 31.25rem){.search-result-previews{display:inline-block;width:60%;padding-left:.5rem;margin-left:0;vertical-align:top}}.search-result-preview+.search-result-preview{margin-top:.25rem}.search-result-highlight{font-weight:bold}.search-no-result{padding:.5rem .75rem;font-size:12px !important}@media (min-width: 31.25rem){.search-no-result{font-size:14px !important}}.search-button{position:fixed;right:1rem;bottom:1rem;display:flex;width:3.5rem;height:3.5rem;background-color:#fff;border:1px solid rgba(83,163,218,0.3);border-radius:1.75rem;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);align-items:center;justify-content:center}.search-overlay{position:fixed;top:0;left:0;z-index:1;width:0;height:0;background-color:rgba(0,0,0,0.3);opacity:0;transition:opacity ease 400ms,width 0s 400ms,height 0s 400ms}.search-active .search{position:fixed;top:0;left:0;width:100%;height:100%;padding:0}.search-active .search-input-wrap{height:4rem;border-radius:0}@media (min-width: 50rem){.search-active .search-input-wrap{width:536px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}}.search-active .search-input{background-color:#fff}@media (min-width: 50rem){.search-active .search-input{padding-left:2.3rem}}@media (min-width: 50rem){.search-active .search-label{padding-left:0.6rem}}.search-active .search-results{display:block}.search-active .search-overlay{width:100%;height:100%;opacity:1;transition:opacity ease 400ms,width 0s,height 0s}@media (min-width: 50rem){.search-active .main{position:fixed;right:0;left:0}}.search-active .main-header{padding-top:4rem}@media (min-width: 50rem){.search-active .main-header{padding-top:0}}.table-wrapper{display:block;width:100%;max-width:100%;margin-bottom:1.5rem;overflow-x:auto;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}table{display:table;min-width:100%;border-collapse:separate}th,td{font-size:12px !important;min-width:120px;padding:.5rem .75rem;background-color:#fff;border-bottom:1px solid rgba(238,235,238,0.5);border-left:1px solid #eeebee}@media (min-width: 31.25rem){th,td{font-size:14px !important}}th:first-of-type,td:first-of-type{border-left:0}tbody tr:last-of-type th,tbody tr:last-of-type td{border-bottom:0}tbody tr:last-of-type td{padding-bottom:.75rem}thead th{border-bottom:1px solid #eeebee}:not(pre,figure)>code{padding:0.2em 0.15em;font-weight:400;background-color:#f5f6fa;border:1px solid #eeebee;border-radius:4px}a:visited code{border-color:#eeebee}div.highlighter-rouge,div.listingblock>div.content,figure.highlight{margin-top:0;margin-bottom:.75rem;background-color:#f5f6fa;border-radius:4px;box-shadow:none;-webkit-overflow-scrolling:touch;position:relative;padding:0}div.highlighter-rouge>button,div.listingblock>div.content>button,figure.highlight>button{width:.75rem;opacity:0;position:absolute;top:0;right:0;border:.75rem solid #f5f6fa;background-color:#f5f6fa;color:#5c5962;box-sizing:content-box}div.highlighter-rouge>button svg,div.listingblock>div.content>button svg,figure.highlight>button svg{fill:#5c5962}div.highlighter-rouge>button:active,div.listingblock>div.content>button:active,figure.highlight>button:active{text-decoration:none;outline:none;opacity:1}div.highlighter-rouge>button:focus,div.listingblock>div.content>button:focus,figure.highlight>button:focus{opacity:1}div.highlighter-rouge:hover>button,div.listingblock>div.content:hover>button,figure.highlight:hover>button{cursor:copy;opacity:1}div.highlighter-rouge div.highlight{overflow-x:auto;padding:.75rem;margin:0;border:0}div.highlighter-rouge pre.highlight,div.highlighter-rouge code{padding:0;margin:0;border:0}div.listingblock{margin-top:0;margin-bottom:.75rem}div.listingblock div.content{overflow-x:auto;padding:.75rem;margin:0;border:0}div.listingblock div.content>pre,div.listingblock code{padding:0;margin:0;border:0}figure.highlight pre,figure.highlight :not(pre)>code{overflow-x:auto;padding:.75rem;margin:0;border:0}.highlight .table-wrapper{padding:.75rem 0;margin:0;border:0;box-shadow:none}.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:11px !important;min-width:0;padding:0;background-color:#f5f6fa;border:0}@media (min-width: 31.25rem){.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:12px !important}}.highlight .table-wrapper td.gl{width:1em;padding-right:.75rem;padding-left:.75rem}.highlight .table-wrapper pre{margin:0;line-height:2}.code-example,.listingblock>.title{padding:.75rem;margin-bottom:.75rem;overflow:auto;border:1px solid #eeebee;border-radius:4px}.code-example+.highlighter-rouge,.code-example+.sectionbody .listingblock,.code-example+.content,.code-example+figure.highlight,.listingblock>.title+.highlighter-rouge,.listingblock>.title+.sectionbody .listingblock,.listingblock>.title+.content,.listingblock>.title+figure.highlight{position:relative;margin-top:-1rem;border-right:1px solid #eeebee;border-bottom:1px solid #eeebee;border-left:1px solid #eeebee;border-top-left-radius:0;border-top-right-radius:0}code.language-mermaid{padding:0;background-color:inherit;border:0}.highlight,pre.highlight{background:#f5f6fa;color:#5c5962}.highlight pre{background:#f5f6fa}.text-grey-dk-000{color:#959396 !important}.text-grey-dk-100{color:#5c5962 !important}.text-grey-dk-200{color:#44434d !important}.text-grey-dk-250{color:#302d36 !important}.text-grey-dk-300{color:#27262b !important}.text-grey-lt-000{color:#f5f6fa !important}.text-grey-lt-100{color:#eeebee !important}.text-grey-lt-200{color:#ecebed !important}.text-grey-lt-300{color:#e6e1e8 !important}.text-blue-000{color:#2c84fa !important}.text-blue-100{color:#2869e6 !important}.text-blue-200{color:#264caf !important}.text-blue-300{color:#183385 !important}.text-green-000{color:#41d693 !important}.text-green-100{color:#11b584 !important}.text-green-200{color:#009c7b !important}.text-green-300{color:#026e57 !important}.text-purple-000{color:#7253ed !important}.text-purple-100{color:#5e41d0 !important}.text-purple-200{color:#4e26af !important}.text-purple-300{color:#381885 !important}.text-yellow-000{color:#ffeb82 !important}.text-yellow-100{color:#fadf50 !important}.text-yellow-200{color:#f7d12e !important}.text-yellow-300{color:#e7af06 !important}.text-red-000{color:#f77e7e !important}.text-red-100{color:#f96e65 !important}.text-red-200{color:#e94c4c !important}.text-red-300{color:#dd2e2e !important}.bg-grey-dk-000{background-color:#959396 !important}.bg-grey-dk-100{background-color:#5c5962 !important}.bg-grey-dk-200{background-color:#44434d !important}.bg-grey-dk-250{background-color:#302d36 !important}.bg-grey-dk-300{background-color:#27262b !important}.bg-grey-lt-000{background-color:#f5f6fa !important}.bg-grey-lt-100{background-color:#eeebee !important}.bg-grey-lt-200{background-color:#ecebed !important}.bg-grey-lt-300{background-color:#e6e1e8 !important}.bg-blue-000{background-color:#2c84fa !important}.bg-blue-100{background-color:#2869e6 !important}.bg-blue-200{background-color:#264caf !important}.bg-blue-300{background-color:#183385 !important}.bg-green-000{background-color:#41d693 !important}.bg-green-100{background-color:#11b584 !important}.bg-green-200{background-color:#009c7b !important}.bg-green-300{background-color:#026e57 !important}.bg-purple-000{background-color:#7253ed !important}.bg-purple-100{background-color:#5e41d0 !important}.bg-purple-200{background-color:#4e26af !important}.bg-purple-300{background-color:#381885 !important}.bg-yellow-000{background-color:#ffeb82 !important}.bg-yellow-100{background-color:#fadf50 !important}.bg-yellow-200{background-color:#f7d12e !important}.bg-yellow-300{background-color:#e7af06 !important}.bg-red-000{background-color:#f77e7e !important}.bg-red-100{background-color:#f96e65 !important}.bg-red-200{background-color:#e94c4c !important}.bg-red-300{background-color:#dd2e2e !important}.d-block{display:block !important}.d-flex{display:flex !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-none{display:none !important}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}.float-left{float:left !important}.float-right{float:right !important}.flex-justify-start{justify-content:flex-start !important}.flex-justify-end{justify-content:flex-end !important}.flex-justify-between{justify-content:space-between !important}.flex-justify-around{justify-content:space-around !important}.v-align-baseline{vertical-align:baseline !important}.v-align-bottom{vertical-align:bottom !important}.v-align-middle{vertical-align:middle !important}.v-align-text-bottom{vertical-align:text-bottom !important}.v-align-text-top{vertical-align:text-top !important}.v-align-top{vertical-align:top !important}.fs-1{font-size:9px !important}@media (min-width: 31.25rem){.fs-1{font-size:10px !important}}.fs-2{font-size:11px !important}@media (min-width: 31.25rem){.fs-2{font-size:12px !important}}.fs-3{font-size:12px !important}@media (min-width: 31.25rem){.fs-3{font-size:14px !important}}.fs-4{font-size:14px !important}@media (min-width: 31.25rem){.fs-4{font-size:16px !important}}.fs-5{font-size:16px !important}@media (min-width: 31.25rem){.fs-5{font-size:18px !important}}.fs-6{font-size:18px !important}@media (min-width: 31.25rem){.fs-6{font-size:24px !important;line-height:1.25}}.fs-7{font-size:24px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-7{font-size:32px !important}}.fs-8{font-size:32px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-8{font-size:36px !important}}.fs-9{font-size:36px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-9{font-size:42px !important}}.fs-10{font-size:42px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-10{font-size:48px !important}}.fw-300{font-weight:300 !important}.fw-400{font-weight:400 !important}.fw-500{font-weight:500 !important}.fw-700{font-weight:700 !important}.lh-0{line-height:0 !important}.lh-default{line-height:1.4}.lh-tight{line-height:1.25}.ls-5{letter-spacing:0.05em !important}.ls-10{letter-spacing:0.1em !important}.ls-0{letter-spacing:0 !important}.text-uppercase{text-transform:uppercase !important}.list-style-none{padding:0 !important;margin:0 !important;list-style:none !important}.list-style-none li::before{display:none !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-0{margin-right:-0 !important;margin-left:-0 !important}.mx-0-auto{margin-right:auto !important;margin-left:auto !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-1{margin-right:-.25rem !important;margin-left:-.25rem !important}.mx-1-auto{margin-right:auto !important;margin-left:auto !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-2{margin-right:-.5rem !important;margin-left:-.5rem !important}.mx-2-auto{margin-right:auto !important;margin-left:auto !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-3{margin-right:-.75rem !important;margin-left:-.75rem !important}.mx-3-auto{margin-right:auto !important;margin-left:auto !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-right:1rem !important;margin-left:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-4{margin-right:-1rem !important;margin-left:-1rem !important}.mx-4-auto{margin-right:auto !important;margin-left:auto !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}.mx-5-auto{margin-right:auto !important;margin-left:auto !important}.m-6{margin:2rem !important}.mt-6{margin-top:2rem !important}.mr-6{margin-right:2rem !important}.mb-6{margin-bottom:2rem !important}.ml-6{margin-left:2rem !important}.mx-6{margin-right:2rem !important;margin-left:2rem !important}.my-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-6{margin-right:-2rem !important;margin-left:-2rem !important}.mx-6-auto{margin-right:auto !important;margin-left:auto !important}.m-7{margin:2.5rem !important}.mt-7{margin-top:2.5rem !important}.mr-7{margin-right:2.5rem !important}.mb-7{margin-bottom:2.5rem !important}.ml-7{margin-left:2.5rem !important}.mx-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}.mx-7-auto{margin-right:auto !important;margin-left:auto !important}.m-8{margin:3rem !important}.mt-8{margin-top:3rem !important}.mr-8{margin-right:3rem !important}.mb-8{margin-bottom:3rem !important}.ml-8{margin-left:3rem !important}.mx-8{margin-right:3rem !important;margin-left:3rem !important}.my-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-8{margin-right:-3rem !important;margin-left:-3rem !important}.mx-8-auto{margin-right:auto !important;margin-left:auto !important}.m-9{margin:3.5rem !important}.mt-9{margin-top:3.5rem !important}.mr-9{margin-right:3.5rem !important}.mb-9{margin-bottom:3.5rem !important}.ml-9{margin-left:3.5rem !important}.mx-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}.mx-9-auto{margin-right:auto !important;margin-left:auto !important}.m-10{margin:4rem !important}.mt-10{margin-top:4rem !important}.mr-10{margin-right:4rem !important}.mb-10{margin-bottom:4rem !important}.ml-10{margin-left:4rem !important}.mx-10{margin-right:4rem !important;margin-left:4rem !important}.my-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-10{margin-right:-4rem !important;margin-left:-4rem !important}.mx-10-auto{margin-right:auto !important;margin-left:auto !important}@media (min-width: 20rem){.m-xs-0{margin:0 !important}.mt-xs-0{margin-top:0 !important}.mr-xs-0{margin-right:0 !important}.mb-xs-0{margin-bottom:0 !important}.ml-xs-0{margin-left:0 !important}.mx-xs-0{margin-right:0 !important;margin-left:0 !important}.my-xs-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xs-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 20rem){.m-xs-1{margin:.25rem !important}.mt-xs-1{margin-top:.25rem !important}.mr-xs-1{margin-right:.25rem !important}.mb-xs-1{margin-bottom:.25rem !important}.ml-xs-1{margin-left:.25rem !important}.mx-xs-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xs-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xs-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 20rem){.m-xs-2{margin:.5rem !important}.mt-xs-2{margin-top:.5rem !important}.mr-xs-2{margin-right:.5rem !important}.mb-xs-2{margin-bottom:.5rem !important}.ml-xs-2{margin-left:.5rem !important}.mx-xs-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xs-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xs-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 20rem){.m-xs-3{margin:.75rem !important}.mt-xs-3{margin-top:.75rem !important}.mr-xs-3{margin-right:.75rem !important}.mb-xs-3{margin-bottom:.75rem !important}.ml-xs-3{margin-left:.75rem !important}.mx-xs-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xs-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xs-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 20rem){.m-xs-4{margin:1rem !important}.mt-xs-4{margin-top:1rem !important}.mr-xs-4{margin-right:1rem !important}.mb-xs-4{margin-bottom:1rem !important}.ml-xs-4{margin-left:1rem !important}.mx-xs-4{margin-right:1rem !important;margin-left:1rem !important}.my-xs-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xs-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 20rem){.m-xs-5{margin:1.5rem !important}.mt-xs-5{margin-top:1.5rem !important}.mr-xs-5{margin-right:1.5rem !important}.mb-xs-5{margin-bottom:1.5rem !important}.ml-xs-5{margin-left:1.5rem !important}.mx-xs-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xs-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xs-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 20rem){.m-xs-6{margin:2rem !important}.mt-xs-6{margin-top:2rem !important}.mr-xs-6{margin-right:2rem !important}.mb-xs-6{margin-bottom:2rem !important}.ml-xs-6{margin-left:2rem !important}.mx-xs-6{margin-right:2rem !important;margin-left:2rem !important}.my-xs-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xs-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 20rem){.m-xs-7{margin:2.5rem !important}.mt-xs-7{margin-top:2.5rem !important}.mr-xs-7{margin-right:2.5rem !important}.mb-xs-7{margin-bottom:2.5rem !important}.ml-xs-7{margin-left:2.5rem !important}.mx-xs-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xs-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xs-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 20rem){.m-xs-8{margin:3rem !important}.mt-xs-8{margin-top:3rem !important}.mr-xs-8{margin-right:3rem !important}.mb-xs-8{margin-bottom:3rem !important}.ml-xs-8{margin-left:3rem !important}.mx-xs-8{margin-right:3rem !important;margin-left:3rem !important}.my-xs-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xs-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 20rem){.m-xs-9{margin:3.5rem !important}.mt-xs-9{margin-top:3.5rem !important}.mr-xs-9{margin-right:3.5rem !important}.mb-xs-9{margin-bottom:3.5rem !important}.ml-xs-9{margin-left:3.5rem !important}.mx-xs-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xs-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xs-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 20rem){.m-xs-10{margin:4rem !important}.mt-xs-10{margin-top:4rem !important}.mr-xs-10{margin-right:4rem !important}.mb-xs-10{margin-bottom:4rem !important}.ml-xs-10{margin-left:4rem !important}.mx-xs-10{margin-right:4rem !important;margin-left:4rem !important}.my-xs-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xs-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 31.25rem){.m-sm-0{margin:0 !important}.mt-sm-0{margin-top:0 !important}.mr-sm-0{margin-right:0 !important}.mb-sm-0{margin-bottom:0 !important}.ml-sm-0{margin-left:0 !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-sm-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 31.25rem){.m-sm-1{margin:.25rem !important}.mt-sm-1{margin-top:.25rem !important}.mr-sm-1{margin-right:.25rem !important}.mb-sm-1{margin-bottom:.25rem !important}.ml-sm-1{margin-left:.25rem !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-sm-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 31.25rem){.m-sm-2{margin:.5rem !important}.mt-sm-2{margin-top:.5rem !important}.mr-sm-2{margin-right:.5rem !important}.mb-sm-2{margin-bottom:.5rem !important}.ml-sm-2{margin-left:.5rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-sm-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 31.25rem){.m-sm-3{margin:.75rem !important}.mt-sm-3{margin-top:.75rem !important}.mr-sm-3{margin-right:.75rem !important}.mb-sm-3{margin-bottom:.75rem !important}.ml-sm-3{margin-left:.75rem !important}.mx-sm-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-sm-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-sm-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 31.25rem){.m-sm-4{margin:1rem !important}.mt-sm-4{margin-top:1rem !important}.mr-sm-4{margin-right:1rem !important}.mb-sm-4{margin-bottom:1rem !important}.ml-sm-4{margin-left:1rem !important}.mx-sm-4{margin-right:1rem !important;margin-left:1rem !important}.my-sm-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-sm-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 31.25rem){.m-sm-5{margin:1.5rem !important}.mt-sm-5{margin-top:1.5rem !important}.mr-sm-5{margin-right:1.5rem !important}.mb-sm-5{margin-bottom:1.5rem !important}.ml-sm-5{margin-left:1.5rem !important}.mx-sm-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-sm-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-sm-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 31.25rem){.m-sm-6{margin:2rem !important}.mt-sm-6{margin-top:2rem !important}.mr-sm-6{margin-right:2rem !important}.mb-sm-6{margin-bottom:2rem !important}.ml-sm-6{margin-left:2rem !important}.mx-sm-6{margin-right:2rem !important;margin-left:2rem !important}.my-sm-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-sm-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 31.25rem){.m-sm-7{margin:2.5rem !important}.mt-sm-7{margin-top:2.5rem !important}.mr-sm-7{margin-right:2.5rem !important}.mb-sm-7{margin-bottom:2.5rem !important}.ml-sm-7{margin-left:2.5rem !important}.mx-sm-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-sm-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-sm-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 31.25rem){.m-sm-8{margin:3rem !important}.mt-sm-8{margin-top:3rem !important}.mr-sm-8{margin-right:3rem !important}.mb-sm-8{margin-bottom:3rem !important}.ml-sm-8{margin-left:3rem !important}.mx-sm-8{margin-right:3rem !important;margin-left:3rem !important}.my-sm-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-sm-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 31.25rem){.m-sm-9{margin:3.5rem !important}.mt-sm-9{margin-top:3.5rem !important}.mr-sm-9{margin-right:3.5rem !important}.mb-sm-9{margin-bottom:3.5rem !important}.ml-sm-9{margin-left:3.5rem !important}.mx-sm-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-sm-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-sm-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 31.25rem){.m-sm-10{margin:4rem !important}.mt-sm-10{margin-top:4rem !important}.mr-sm-10{margin-right:4rem !important}.mb-sm-10{margin-bottom:4rem !important}.ml-sm-10{margin-left:4rem !important}.mx-sm-10{margin-right:4rem !important;margin-left:4rem !important}.my-sm-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-sm-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 50rem){.m-md-0{margin:0 !important}.mt-md-0{margin-top:0 !important}.mr-md-0{margin-right:0 !important}.mb-md-0{margin-bottom:0 !important}.ml-md-0{margin-left:0 !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-md-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 50rem){.m-md-1{margin:.25rem !important}.mt-md-1{margin-top:.25rem !important}.mr-md-1{margin-right:.25rem !important}.mb-md-1{margin-bottom:.25rem !important}.ml-md-1{margin-left:.25rem !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-md-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 50rem){.m-md-2{margin:.5rem !important}.mt-md-2{margin-top:.5rem !important}.mr-md-2{margin-right:.5rem !important}.mb-md-2{margin-bottom:.5rem !important}.ml-md-2{margin-left:.5rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-md-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 50rem){.m-md-3{margin:.75rem !important}.mt-md-3{margin-top:.75rem !important}.mr-md-3{margin-right:.75rem !important}.mb-md-3{margin-bottom:.75rem !important}.ml-md-3{margin-left:.75rem !important}.mx-md-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-md-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-md-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 50rem){.m-md-4{margin:1rem !important}.mt-md-4{margin-top:1rem !important}.mr-md-4{margin-right:1rem !important}.mb-md-4{margin-bottom:1rem !important}.ml-md-4{margin-left:1rem !important}.mx-md-4{margin-right:1rem !important;margin-left:1rem !important}.my-md-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-md-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 50rem){.m-md-5{margin:1.5rem !important}.mt-md-5{margin-top:1.5rem !important}.mr-md-5{margin-right:1.5rem !important}.mb-md-5{margin-bottom:1.5rem !important}.ml-md-5{margin-left:1.5rem !important}.mx-md-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-md-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-md-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 50rem){.m-md-6{margin:2rem !important}.mt-md-6{margin-top:2rem !important}.mr-md-6{margin-right:2rem !important}.mb-md-6{margin-bottom:2rem !important}.ml-md-6{margin-left:2rem !important}.mx-md-6{margin-right:2rem !important;margin-left:2rem !important}.my-md-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-md-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 50rem){.m-md-7{margin:2.5rem !important}.mt-md-7{margin-top:2.5rem !important}.mr-md-7{margin-right:2.5rem !important}.mb-md-7{margin-bottom:2.5rem !important}.ml-md-7{margin-left:2.5rem !important}.mx-md-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-md-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-md-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 50rem){.m-md-8{margin:3rem !important}.mt-md-8{margin-top:3rem !important}.mr-md-8{margin-right:3rem !important}.mb-md-8{margin-bottom:3rem !important}.ml-md-8{margin-left:3rem !important}.mx-md-8{margin-right:3rem !important;margin-left:3rem !important}.my-md-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-md-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 50rem){.m-md-9{margin:3.5rem !important}.mt-md-9{margin-top:3.5rem !important}.mr-md-9{margin-right:3.5rem !important}.mb-md-9{margin-bottom:3.5rem !important}.ml-md-9{margin-left:3.5rem !important}.mx-md-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-md-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-md-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 50rem){.m-md-10{margin:4rem !important}.mt-md-10{margin-top:4rem !important}.mr-md-10{margin-right:4rem !important}.mb-md-10{margin-bottom:4rem !important}.ml-md-10{margin-left:4rem !important}.mx-md-10{margin-right:4rem !important;margin-left:4rem !important}.my-md-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-md-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 66.5rem){.m-lg-0{margin:0 !important}.mt-lg-0{margin-top:0 !important}.mr-lg-0{margin-right:0 !important}.mb-lg-0{margin-bottom:0 !important}.ml-lg-0{margin-left:0 !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-lg-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 66.5rem){.m-lg-1{margin:.25rem !important}.mt-lg-1{margin-top:.25rem !important}.mr-lg-1{margin-right:.25rem !important}.mb-lg-1{margin-bottom:.25rem !important}.ml-lg-1{margin-left:.25rem !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-lg-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 66.5rem){.m-lg-2{margin:.5rem !important}.mt-lg-2{margin-top:.5rem !important}.mr-lg-2{margin-right:.5rem !important}.mb-lg-2{margin-bottom:.5rem !important}.ml-lg-2{margin-left:.5rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-lg-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 66.5rem){.m-lg-3{margin:.75rem !important}.mt-lg-3{margin-top:.75rem !important}.mr-lg-3{margin-right:.75rem !important}.mb-lg-3{margin-bottom:.75rem !important}.ml-lg-3{margin-left:.75rem !important}.mx-lg-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-lg-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-lg-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 66.5rem){.m-lg-4{margin:1rem !important}.mt-lg-4{margin-top:1rem !important}.mr-lg-4{margin-right:1rem !important}.mb-lg-4{margin-bottom:1rem !important}.ml-lg-4{margin-left:1rem !important}.mx-lg-4{margin-right:1rem !important;margin-left:1rem !important}.my-lg-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-lg-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 66.5rem){.m-lg-5{margin:1.5rem !important}.mt-lg-5{margin-top:1.5rem !important}.mr-lg-5{margin-right:1.5rem !important}.mb-lg-5{margin-bottom:1.5rem !important}.ml-lg-5{margin-left:1.5rem !important}.mx-lg-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-lg-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-lg-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 66.5rem){.m-lg-6{margin:2rem !important}.mt-lg-6{margin-top:2rem !important}.mr-lg-6{margin-right:2rem !important}.mb-lg-6{margin-bottom:2rem !important}.ml-lg-6{margin-left:2rem !important}.mx-lg-6{margin-right:2rem !important;margin-left:2rem !important}.my-lg-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-lg-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 66.5rem){.m-lg-7{margin:2.5rem !important}.mt-lg-7{margin-top:2.5rem !important}.mr-lg-7{margin-right:2.5rem !important}.mb-lg-7{margin-bottom:2.5rem !important}.ml-lg-7{margin-left:2.5rem !important}.mx-lg-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-lg-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-lg-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 66.5rem){.m-lg-8{margin:3rem !important}.mt-lg-8{margin-top:3rem !important}.mr-lg-8{margin-right:3rem !important}.mb-lg-8{margin-bottom:3rem !important}.ml-lg-8{margin-left:3rem !important}.mx-lg-8{margin-right:3rem !important;margin-left:3rem !important}.my-lg-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-lg-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 66.5rem){.m-lg-9{margin:3.5rem !important}.mt-lg-9{margin-top:3.5rem !important}.mr-lg-9{margin-right:3.5rem !important}.mb-lg-9{margin-bottom:3.5rem !important}.ml-lg-9{margin-left:3.5rem !important}.mx-lg-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-lg-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-lg-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 66.5rem){.m-lg-10{margin:4rem !important}.mt-lg-10{margin-top:4rem !important}.mr-lg-10{margin-right:4rem !important}.mb-lg-10{margin-bottom:4rem !important}.ml-lg-10{margin-left:4rem !important}.mx-lg-10{margin-right:4rem !important;margin-left:4rem !important}.my-lg-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-lg-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 87.5rem){.m-xl-0{margin:0 !important}.mt-xl-0{margin-top:0 !important}.mr-xl-0{margin-right:0 !important}.mb-xl-0{margin-bottom:0 !important}.ml-xl-0{margin-left:0 !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xl-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 87.5rem){.m-xl-1{margin:.25rem !important}.mt-xl-1{margin-top:.25rem !important}.mr-xl-1{margin-right:.25rem !important}.mb-xl-1{margin-bottom:.25rem !important}.ml-xl-1{margin-left:.25rem !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xl-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 87.5rem){.m-xl-2{margin:.5rem !important}.mt-xl-2{margin-top:.5rem !important}.mr-xl-2{margin-right:.5rem !important}.mb-xl-2{margin-bottom:.5rem !important}.ml-xl-2{margin-left:.5rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xl-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 87.5rem){.m-xl-3{margin:.75rem !important}.mt-xl-3{margin-top:.75rem !important}.mr-xl-3{margin-right:.75rem !important}.mb-xl-3{margin-bottom:.75rem !important}.ml-xl-3{margin-left:.75rem !important}.mx-xl-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xl-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xl-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 87.5rem){.m-xl-4{margin:1rem !important}.mt-xl-4{margin-top:1rem !important}.mr-xl-4{margin-right:1rem !important}.mb-xl-4{margin-bottom:1rem !important}.ml-xl-4{margin-left:1rem !important}.mx-xl-4{margin-right:1rem !important;margin-left:1rem !important}.my-xl-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xl-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 87.5rem){.m-xl-5{margin:1.5rem !important}.mt-xl-5{margin-top:1.5rem !important}.mr-xl-5{margin-right:1.5rem !important}.mb-xl-5{margin-bottom:1.5rem !important}.ml-xl-5{margin-left:1.5rem !important}.mx-xl-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xl-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xl-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 87.5rem){.m-xl-6{margin:2rem !important}.mt-xl-6{margin-top:2rem !important}.mr-xl-6{margin-right:2rem !important}.mb-xl-6{margin-bottom:2rem !important}.ml-xl-6{margin-left:2rem !important}.mx-xl-6{margin-right:2rem !important;margin-left:2rem !important}.my-xl-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xl-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 87.5rem){.m-xl-7{margin:2.5rem !important}.mt-xl-7{margin-top:2.5rem !important}.mr-xl-7{margin-right:2.5rem !important}.mb-xl-7{margin-bottom:2.5rem !important}.ml-xl-7{margin-left:2.5rem !important}.mx-xl-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xl-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xl-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 87.5rem){.m-xl-8{margin:3rem !important}.mt-xl-8{margin-top:3rem !important}.mr-xl-8{margin-right:3rem !important}.mb-xl-8{margin-bottom:3rem !important}.ml-xl-8{margin-left:3rem !important}.mx-xl-8{margin-right:3rem !important;margin-left:3rem !important}.my-xl-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xl-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 87.5rem){.m-xl-9{margin:3.5rem !important}.mt-xl-9{margin-top:3.5rem !important}.mr-xl-9{margin-right:3.5rem !important}.mb-xl-9{margin-bottom:3.5rem !important}.ml-xl-9{margin-left:3.5rem !important}.mx-xl-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xl-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xl-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 87.5rem){.m-xl-10{margin:4rem !important}.mt-xl-10{margin-top:4rem !important}.mr-xl-10{margin-right:4rem !important}.mb-xl-10{margin-bottom:4rem !important}.ml-xl-10{margin-left:4rem !important}.mx-xl-10{margin-right:4rem !important;margin-left:4rem !important}.my-xl-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xl-10{margin-right:-4rem !important;margin-left:-4rem !important}}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-right:0 !important;padding-left:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-right:1rem !important;padding-left:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:2rem !important}.pt-6{padding-top:2rem !important}.pr-6{padding-right:2rem !important}.pb-6{padding-bottom:2rem !important}.pl-6{padding-left:2rem !important}.px-6{padding-right:2rem !important;padding-left:2rem !important}.py-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-7{padding:2.5rem !important}.pt-7{padding-top:2.5rem !important}.pr-7{padding-right:2.5rem !important}.pb-7{padding-bottom:2.5rem !important}.pl-7{padding-left:2.5rem !important}.px-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-8{padding:3rem !important}.pt-8{padding-top:3rem !important}.pr-8{padding-right:3rem !important}.pb-8{padding-bottom:3rem !important}.pl-8{padding-left:3rem !important}.px-8{padding-right:3rem !important;padding-left:3rem !important}.py-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-9{padding:3.5rem !important}.pt-9{padding-top:3.5rem !important}.pr-9{padding-right:3.5rem !important}.pb-9{padding-bottom:3.5rem !important}.pl-9{padding-left:3.5rem !important}.px-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-10{padding:4rem !important}.pt-10{padding-top:4rem !important}.pr-10{padding-right:4rem !important}.pb-10{padding-bottom:4rem !important}.pl-10{padding-left:4rem !important}.px-10{padding-right:4rem !important;padding-left:4rem !important}.py-10{padding-top:4rem !important;padding-bottom:4rem !important}@media (min-width: 20rem){.p-xs-0{padding:0 !important}.pt-xs-0{padding-top:0 !important}.pr-xs-0{padding-right:0 !important}.pb-xs-0{padding-bottom:0 !important}.pl-xs-0{padding-left:0 !important}.px-xs-0{padding-right:0 !important;padding-left:0 !important}.py-xs-0{padding-top:0 !important;padding-bottom:0 !important}.p-xs-1{padding:.25rem !important}.pt-xs-1{padding-top:.25rem !important}.pr-xs-1{padding-right:.25rem !important}.pb-xs-1{padding-bottom:.25rem !important}.pl-xs-1{padding-left:.25rem !important}.px-xs-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xs-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xs-2{padding:.5rem !important}.pt-xs-2{padding-top:.5rem !important}.pr-xs-2{padding-right:.5rem !important}.pb-xs-2{padding-bottom:.5rem !important}.pl-xs-2{padding-left:.5rem !important}.px-xs-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xs-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xs-3{padding:.75rem !important}.pt-xs-3{padding-top:.75rem !important}.pr-xs-3{padding-right:.75rem !important}.pb-xs-3{padding-bottom:.75rem !important}.pl-xs-3{padding-left:.75rem !important}.px-xs-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xs-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xs-4{padding:1rem !important}.pt-xs-4{padding-top:1rem !important}.pr-xs-4{padding-right:1rem !important}.pb-xs-4{padding-bottom:1rem !important}.pl-xs-4{padding-left:1rem !important}.px-xs-4{padding-right:1rem !important;padding-left:1rem !important}.py-xs-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xs-5{padding:1.5rem !important}.pt-xs-5{padding-top:1.5rem !important}.pr-xs-5{padding-right:1.5rem !important}.pb-xs-5{padding-bottom:1.5rem !important}.pl-xs-5{padding-left:1.5rem !important}.px-xs-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xs-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xs-6{padding:2rem !important}.pt-xs-6{padding-top:2rem !important}.pr-xs-6{padding-right:2rem !important}.pb-xs-6{padding-bottom:2rem !important}.pl-xs-6{padding-left:2rem !important}.px-xs-6{padding-right:2rem !important;padding-left:2rem !important}.py-xs-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xs-7{padding:2.5rem !important}.pt-xs-7{padding-top:2.5rem !important}.pr-xs-7{padding-right:2.5rem !important}.pb-xs-7{padding-bottom:2.5rem !important}.pl-xs-7{padding-left:2.5rem !important}.px-xs-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xs-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xs-8{padding:3rem !important}.pt-xs-8{padding-top:3rem !important}.pr-xs-8{padding-right:3rem !important}.pb-xs-8{padding-bottom:3rem !important}.pl-xs-8{padding-left:3rem !important}.px-xs-8{padding-right:3rem !important;padding-left:3rem !important}.py-xs-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xs-9{padding:3.5rem !important}.pt-xs-9{padding-top:3.5rem !important}.pr-xs-9{padding-right:3.5rem !important}.pb-xs-9{padding-bottom:3.5rem !important}.pl-xs-9{padding-left:3.5rem !important}.px-xs-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xs-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xs-10{padding:4rem !important}.pt-xs-10{padding-top:4rem !important}.pr-xs-10{padding-right:4rem !important}.pb-xs-10{padding-bottom:4rem !important}.pl-xs-10{padding-left:4rem !important}.px-xs-10{padding-right:4rem !important;padding-left:4rem !important}.py-xs-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 31.25rem){.p-sm-0{padding:0 !important}.pt-sm-0{padding-top:0 !important}.pr-sm-0{padding-right:0 !important}.pb-sm-0{padding-bottom:0 !important}.pl-sm-0{padding-left:0 !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1{padding-top:.25rem !important}.pr-sm-1{padding-right:.25rem !important}.pb-sm-1{padding-bottom:.25rem !important}.pl-sm-1{padding-left:.25rem !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2{padding-top:.5rem !important}.pr-sm-2{padding-right:.5rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pl-sm-2{padding-left:.5rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-sm-3{padding:.75rem !important}.pt-sm-3{padding-top:.75rem !important}.pr-sm-3{padding-right:.75rem !important}.pb-sm-3{padding-bottom:.75rem !important}.pl-sm-3{padding-left:.75rem !important}.px-sm-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-sm-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-sm-4{padding:1rem !important}.pt-sm-4{padding-top:1rem !important}.pr-sm-4{padding-right:1rem !important}.pb-sm-4{padding-bottom:1rem !important}.pl-sm-4{padding-left:1rem !important}.px-sm-4{padding-right:1rem !important;padding-left:1rem !important}.py-sm-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-sm-5{padding:1.5rem !important}.pt-sm-5{padding-top:1.5rem !important}.pr-sm-5{padding-right:1.5rem !important}.pb-sm-5{padding-bottom:1.5rem !important}.pl-sm-5{padding-left:1.5rem !important}.px-sm-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-sm-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-sm-6{padding:2rem !important}.pt-sm-6{padding-top:2rem !important}.pr-sm-6{padding-right:2rem !important}.pb-sm-6{padding-bottom:2rem !important}.pl-sm-6{padding-left:2rem !important}.px-sm-6{padding-right:2rem !important;padding-left:2rem !important}.py-sm-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-sm-7{padding:2.5rem !important}.pt-sm-7{padding-top:2.5rem !important}.pr-sm-7{padding-right:2.5rem !important}.pb-sm-7{padding-bottom:2.5rem !important}.pl-sm-7{padding-left:2.5rem !important}.px-sm-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-sm-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-sm-8{padding:3rem !important}.pt-sm-8{padding-top:3rem !important}.pr-sm-8{padding-right:3rem !important}.pb-sm-8{padding-bottom:3rem !important}.pl-sm-8{padding-left:3rem !important}.px-sm-8{padding-right:3rem !important;padding-left:3rem !important}.py-sm-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-sm-9{padding:3.5rem !important}.pt-sm-9{padding-top:3.5rem !important}.pr-sm-9{padding-right:3.5rem !important}.pb-sm-9{padding-bottom:3.5rem !important}.pl-sm-9{padding-left:3.5rem !important}.px-sm-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-sm-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-sm-10{padding:4rem !important}.pt-sm-10{padding-top:4rem !important}.pr-sm-10{padding-right:4rem !important}.pb-sm-10{padding-bottom:4rem !important}.pl-sm-10{padding-left:4rem !important}.px-sm-10{padding-right:4rem !important;padding-left:4rem !important}.py-sm-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 50rem){.p-md-0{padding:0 !important}.pt-md-0{padding-top:0 !important}.pr-md-0{padding-right:0 !important}.pb-md-0{padding-bottom:0 !important}.pl-md-0{padding-left:0 !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1{padding-top:.25rem !important}.pr-md-1{padding-right:.25rem !important}.pb-md-1{padding-bottom:.25rem !important}.pl-md-1{padding-left:.25rem !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2{padding-top:.5rem !important}.pr-md-2{padding-right:.5rem !important}.pb-md-2{padding-bottom:.5rem !important}.pl-md-2{padding-left:.5rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-md-3{padding:.75rem !important}.pt-md-3{padding-top:.75rem !important}.pr-md-3{padding-right:.75rem !important}.pb-md-3{padding-bottom:.75rem !important}.pl-md-3{padding-left:.75rem !important}.px-md-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-md-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-md-4{padding:1rem !important}.pt-md-4{padding-top:1rem !important}.pr-md-4{padding-right:1rem !important}.pb-md-4{padding-bottom:1rem !important}.pl-md-4{padding-left:1rem !important}.px-md-4{padding-right:1rem !important;padding-left:1rem !important}.py-md-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-md-5{padding:1.5rem !important}.pt-md-5{padding-top:1.5rem !important}.pr-md-5{padding-right:1.5rem !important}.pb-md-5{padding-bottom:1.5rem !important}.pl-md-5{padding-left:1.5rem !important}.px-md-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-md-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-md-6{padding:2rem !important}.pt-md-6{padding-top:2rem !important}.pr-md-6{padding-right:2rem !important}.pb-md-6{padding-bottom:2rem !important}.pl-md-6{padding-left:2rem !important}.px-md-6{padding-right:2rem !important;padding-left:2rem !important}.py-md-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-md-7{padding:2.5rem !important}.pt-md-7{padding-top:2.5rem !important}.pr-md-7{padding-right:2.5rem !important}.pb-md-7{padding-bottom:2.5rem !important}.pl-md-7{padding-left:2.5rem !important}.px-md-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-md-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-md-8{padding:3rem !important}.pt-md-8{padding-top:3rem !important}.pr-md-8{padding-right:3rem !important}.pb-md-8{padding-bottom:3rem !important}.pl-md-8{padding-left:3rem !important}.px-md-8{padding-right:3rem !important;padding-left:3rem !important}.py-md-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-md-9{padding:3.5rem !important}.pt-md-9{padding-top:3.5rem !important}.pr-md-9{padding-right:3.5rem !important}.pb-md-9{padding-bottom:3.5rem !important}.pl-md-9{padding-left:3.5rem !important}.px-md-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-md-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-md-10{padding:4rem !important}.pt-md-10{padding-top:4rem !important}.pr-md-10{padding-right:4rem !important}.pb-md-10{padding-bottom:4rem !important}.pl-md-10{padding-left:4rem !important}.px-md-10{padding-right:4rem !important;padding-left:4rem !important}.py-md-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 66.5rem){.p-lg-0{padding:0 !important}.pt-lg-0{padding-top:0 !important}.pr-lg-0{padding-right:0 !important}.pb-lg-0{padding-bottom:0 !important}.pl-lg-0{padding-left:0 !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1{padding-top:.25rem !important}.pr-lg-1{padding-right:.25rem !important}.pb-lg-1{padding-bottom:.25rem !important}.pl-lg-1{padding-left:.25rem !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2{padding-top:.5rem !important}.pr-lg-2{padding-right:.5rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pl-lg-2{padding-left:.5rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-lg-3{padding:.75rem !important}.pt-lg-3{padding-top:.75rem !important}.pr-lg-3{padding-right:.75rem !important}.pb-lg-3{padding-bottom:.75rem !important}.pl-lg-3{padding-left:.75rem !important}.px-lg-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-lg-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-lg-4{padding:1rem !important}.pt-lg-4{padding-top:1rem !important}.pr-lg-4{padding-right:1rem !important}.pb-lg-4{padding-bottom:1rem !important}.pl-lg-4{padding-left:1rem !important}.px-lg-4{padding-right:1rem !important;padding-left:1rem !important}.py-lg-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-lg-5{padding:1.5rem !important}.pt-lg-5{padding-top:1.5rem !important}.pr-lg-5{padding-right:1.5rem !important}.pb-lg-5{padding-bottom:1.5rem !important}.pl-lg-5{padding-left:1.5rem !important}.px-lg-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-lg-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-lg-6{padding:2rem !important}.pt-lg-6{padding-top:2rem !important}.pr-lg-6{padding-right:2rem !important}.pb-lg-6{padding-bottom:2rem !important}.pl-lg-6{padding-left:2rem !important}.px-lg-6{padding-right:2rem !important;padding-left:2rem !important}.py-lg-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-lg-7{padding:2.5rem !important}.pt-lg-7{padding-top:2.5rem !important}.pr-lg-7{padding-right:2.5rem !important}.pb-lg-7{padding-bottom:2.5rem !important}.pl-lg-7{padding-left:2.5rem !important}.px-lg-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-lg-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-lg-8{padding:3rem !important}.pt-lg-8{padding-top:3rem !important}.pr-lg-8{padding-right:3rem !important}.pb-lg-8{padding-bottom:3rem !important}.pl-lg-8{padding-left:3rem !important}.px-lg-8{padding-right:3rem !important;padding-left:3rem !important}.py-lg-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-lg-9{padding:3.5rem !important}.pt-lg-9{padding-top:3.5rem !important}.pr-lg-9{padding-right:3.5rem !important}.pb-lg-9{padding-bottom:3.5rem !important}.pl-lg-9{padding-left:3.5rem !important}.px-lg-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-lg-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-lg-10{padding:4rem !important}.pt-lg-10{padding-top:4rem !important}.pr-lg-10{padding-right:4rem !important}.pb-lg-10{padding-bottom:4rem !important}.pl-lg-10{padding-left:4rem !important}.px-lg-10{padding-right:4rem !important;padding-left:4rem !important}.py-lg-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 87.5rem){.p-xl-0{padding:0 !important}.pt-xl-0{padding-top:0 !important}.pr-xl-0{padding-right:0 !important}.pb-xl-0{padding-bottom:0 !important}.pl-xl-0{padding-left:0 !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1{padding-top:.25rem !important}.pr-xl-1{padding-right:.25rem !important}.pb-xl-1{padding-bottom:.25rem !important}.pl-xl-1{padding-left:.25rem !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2{padding-top:.5rem !important}.pr-xl-2{padding-right:.5rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pl-xl-2{padding-left:.5rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xl-3{padding:.75rem !important}.pt-xl-3{padding-top:.75rem !important}.pr-xl-3{padding-right:.75rem !important}.pb-xl-3{padding-bottom:.75rem !important}.pl-xl-3{padding-left:.75rem !important}.px-xl-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xl-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xl-4{padding:1rem !important}.pt-xl-4{padding-top:1rem !important}.pr-xl-4{padding-right:1rem !important}.pb-xl-4{padding-bottom:1rem !important}.pl-xl-4{padding-left:1rem !important}.px-xl-4{padding-right:1rem !important;padding-left:1rem !important}.py-xl-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xl-5{padding:1.5rem !important}.pt-xl-5{padding-top:1.5rem !important}.pr-xl-5{padding-right:1.5rem !important}.pb-xl-5{padding-bottom:1.5rem !important}.pl-xl-5{padding-left:1.5rem !important}.px-xl-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xl-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xl-6{padding:2rem !important}.pt-xl-6{padding-top:2rem !important}.pr-xl-6{padding-right:2rem !important}.pb-xl-6{padding-bottom:2rem !important}.pl-xl-6{padding-left:2rem !important}.px-xl-6{padding-right:2rem !important;padding-left:2rem !important}.py-xl-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xl-7{padding:2.5rem !important}.pt-xl-7{padding-top:2.5rem !important}.pr-xl-7{padding-right:2.5rem !important}.pb-xl-7{padding-bottom:2.5rem !important}.pl-xl-7{padding-left:2.5rem !important}.px-xl-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xl-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xl-8{padding:3rem !important}.pt-xl-8{padding-top:3rem !important}.pr-xl-8{padding-right:3rem !important}.pb-xl-8{padding-bottom:3rem !important}.pl-xl-8{padding-left:3rem !important}.px-xl-8{padding-right:3rem !important;padding-left:3rem !important}.py-xl-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xl-9{padding:3.5rem !important}.pt-xl-9{padding-top:3.5rem !important}.pr-xl-9{padding-right:3.5rem !important}.pb-xl-9{padding-bottom:3.5rem !important}.pl-xl-9{padding-left:3.5rem !important}.px-xl-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xl-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xl-10{padding:4rem !important}.pt-xl-10{padding-top:4rem !important}.pr-xl-10{padding-right:4rem !important}.pb-xl-10{padding-bottom:4rem !important}.pl-xl-10{padding-left:4rem !important}.px-xl-10{padding-right:4rem !important;padding-left:4rem !important}.py-xl-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media print{.site-footer,.site-button,#edit-this-page,#back-to-top,.site-nav,.main-header{display:none !important}.side-bar{width:100%;height:auto;border-right:0 !important}.site-header{border-bottom:1px solid #eeebee}.site-title{font-size:16px !important;font-weight:700 !important}.text-small{font-size:8pt !important}pre.highlight{border:1px solid #eeebee}.main{max-width:none;margin-left:0}}a.skip-to-main{left:-999px;position:absolute;top:auto;width:1px;height:1px;overflow:hidden;z-index:-999}a.skip-to-main:focus,a.skip-to-main:active{color:#53a3da;background-color:#fff;left:auto;top:auto;width:30%;height:auto;overflow:auto;margin:10px 35%;padding:5px;border-radius:15px;border:4px solid #5e41d0;text-align:center;font-size:1.2em;z-index:999}div.opaque{background-color:#fff} diff --git a/assets/css/just-the-docs-light.css b/assets/css/just-the-docs-light.css new file mode 100644 index 0000000000..1384731931 --- /dev/null +++ b/assets/css/just-the-docs-light.css @@ -0,0 +1 @@ +.highlight .c{color:#586e75}.highlight .err{color:#93a1a1}.highlight .g{color:#93a1a1}.highlight .k{color:#859900}.highlight .l{color:#93a1a1}.highlight .n{color:#93a1a1}.highlight .o{color:#859900}.highlight .x{color:#cb4b16}.highlight .p{color:#93a1a1}.highlight .cm{color:#586e75}.highlight .cp{color:#859900}.highlight .c1{color:#586e75}.highlight .cs{color:#859900}.highlight .gd{color:#2aa198}.highlight .ge{font-style:italic;color:#93a1a1}.highlight .gr{color:#dc322f}.highlight .gh{color:#cb4b16}.highlight .gi{color:#859900}.highlight .go{color:#93a1a1}.highlight .gp{color:#93a1a1}.highlight .gs{font-weight:bold;color:#93a1a1}.highlight .gu{color:#cb4b16}.highlight .gt{color:#93a1a1}.highlight .kc{color:#cb4b16}.highlight .kd{color:#268bd2}.highlight .kn{color:#859900}.highlight .kp{color:#859900}.highlight .kr{color:#268bd2}.highlight .kt{color:#dc322f}.highlight .ld{color:#93a1a1}.highlight .m{color:#2aa198}.highlight .s{color:#2aa198}.highlight .na{color:#555}.highlight .nb{color:#b58900}.highlight .nc{color:#268bd2}.highlight .no{color:#cb4b16}.highlight .nd{color:#268bd2}.highlight .ni{color:#cb4b16}.highlight .ne{color:#cb4b16}.highlight .nf{color:#268bd2}.highlight .nl{color:#555}.highlight .nn{color:#93a1a1}.highlight .nx{color:#555}.highlight .py{color:#93a1a1}.highlight .nt{color:#268bd2}.highlight .nv{color:#268bd2}.highlight .ow{color:#859900}.highlight .w{color:#93a1a1}.highlight .mf{color:#2aa198}.highlight .mh{color:#2aa198}.highlight .mi{color:#2aa198}.highlight .mo{color:#2aa198}.highlight .sb{color:#586e75}.highlight .sc{color:#2aa198}.highlight .sd{color:#93a1a1}.highlight .s2{color:#2aa198}.highlight .se{color:#cb4b16}.highlight .sh{color:#93a1a1}.highlight .si{color:#2aa198}.highlight .sx{color:#2aa198}.highlight .sr{color:#dc322f}.highlight .s1{color:#2aa198}.highlight .ss{color:#2aa198}.highlight .bp{color:#268bd2}.highlight .vc{color:#268bd2}.highlight .vg{color:#268bd2}.highlight .vi{color:#268bd2}.highlight .il{color:#2aa198}.highlight .c{color:#586e75}.highlight .err{color:#93a1a1}.highlight .g{color:#93a1a1}.highlight .k{color:#859900}.highlight .l{color:#93a1a1}.highlight .n{color:#93a1a1}.highlight .o{color:#859900}.highlight .x{color:#cb4b16}.highlight .p{color:#93a1a1}.highlight .cm{color:#586e75}.highlight .cp{color:#859900}.highlight .c1{color:#586e75}.highlight .cs{color:#859900}.highlight .gd{color:#2aa198}.highlight .ge{font-style:italic;color:#93a1a1}.highlight .gr{color:#dc322f}.highlight .gh{color:#cb4b16}.highlight .gi{color:#859900}.highlight .go{color:#93a1a1}.highlight .gp{color:#93a1a1}.highlight .gs{font-weight:bold;color:#93a1a1}.highlight .gu{color:#cb4b16}.highlight .gt{color:#93a1a1}.highlight .kc{color:#cb4b16}.highlight .kd{color:#268bd2}.highlight .kn{color:#859900}.highlight .kp{color:#859900}.highlight .kr{color:#268bd2}.highlight .kt{color:#dc322f}.highlight .ld{color:#93a1a1}.highlight .m{color:#2aa198}.highlight .s{color:#2aa198}.highlight .na{color:#555}.highlight .nb{color:#b58900}.highlight .nc{color:#268bd2}.highlight .no{color:#cb4b16}.highlight .nd{color:#268bd2}.highlight .ni{color:#cb4b16}.highlight .ne{color:#cb4b16}.highlight .nf{color:#268bd2}.highlight .nl{color:#555}.highlight .nn{color:#93a1a1}.highlight .nx{color:#555}.highlight .py{color:#93a1a1}.highlight .nt{color:#268bd2}.highlight .nv{color:#268bd2}.highlight .ow{color:#859900}.highlight .w{color:#93a1a1}.highlight .mf{color:#2aa198}.highlight .mh{color:#2aa198}.highlight .mi{color:#2aa198}.highlight .mo{color:#2aa198}.highlight .sb{color:#586e75}.highlight .sc{color:#2aa198}.highlight .sd{color:#93a1a1}.highlight .s2{color:#2aa198}.highlight .se{color:#cb4b16}.highlight .sh{color:#93a1a1}.highlight .si{color:#2aa198}.highlight .sx{color:#2aa198}.highlight .sr{color:#dc322f}.highlight .s1{color:#2aa198}.highlight .ss{color:#2aa198}.highlight .bp{color:#268bd2}.highlight .vc{color:#268bd2}.highlight .vg{color:#268bd2}.highlight .vi{color:#268bd2}.highlight .il{color:#2aa198}/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace, monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace, monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}*{box-sizing:border-box}::selection{color:#fff;background:#7253ed}html{font-size:14px !important;scroll-behavior:smooth}@media (min-width: 31.25rem){html{font-size:16px !important}}body{font-family:system-ui,-apple-system,blinkmacsystemfont,"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif;font-size:inherit;line-height:1.4;color:#5c5962;background-color:#fff;overflow-wrap:break-word}ol,ul,dl,pre,address,blockquote,table,div,hr,form,fieldset,noscript .table-wrapper{margin-top:0}h1,h2,h3,h4,h5,h6,#toctitle{margin-top:0;margin-bottom:1em;font-weight:500;line-height:1.25;color:#27262b}p{margin-top:1em;margin-bottom:1em}a{color:#7253ed;text-decoration:none}a:not([class]){text-decoration:underline;text-decoration-color:#eeebee;text-underline-offset:2px}a:not([class]):hover{text-decoration-color:rgba(114,83,237,0.45)}code{font-family:"SFMono-Regular",menlo,consolas,monospace;font-size:0.75em;line-height:1.4}figure,pre{margin:0}li{margin:0.25em 0}img{max-width:100%;height:auto}hr{height:1px;padding:0;margin:2rem 0;background-color:#eeebee;border:0}blockquote{margin:10px 0;margin-block-start:0;margin-inline-start:0;padding-left:15px;border-left:3px solid #eeebee}.side-bar{z-index:0;display:flex;flex-wrap:wrap;background-color:#f5f6fa}@media (min-width: 50rem){.side-bar{flex-flow:column nowrap;position:fixed;width:248px;height:100%;border-right:1px solid #eeebee;align-items:flex-end}}@media (min-width: 66.5rem){.side-bar{width:calc((100% - 1064px) / 2 + 264px);min-width:264px}}@media (min-width: 50rem){.main{position:relative;max-width:800px;margin-left:248px}}@media (min-width: 66.5rem){.main{margin-left:Max(264px, calc((100% - 1064px) / 2 + 264px))}}.main-content-wrap{padding-right:1rem;padding-left:1rem;padding-top:1rem;padding-bottom:1rem}@media (min-width: 50rem){.main-content-wrap{padding-right:2rem;padding-left:2rem}}@media (min-width: 50rem){.main-content-wrap{padding-top:2rem;padding-bottom:2rem}}.main-header{z-index:0;display:none;background-color:#f5f6fa}@media (min-width: 50rem){.main-header{display:flex;justify-content:space-between;height:60px;background-color:#fff;border-bottom:1px solid #eeebee}}.main-header.nav-open{display:block}@media (min-width: 50rem){.main-header.nav-open{display:flex}}.site-nav,.site-header,.site-footer{width:100%}@media (min-width: 66.5rem){.site-nav,.site-header,.site-footer{width:264px}}.site-nav{display:none}.site-nav.nav-open{display:block}@media (min-width: 50rem){.site-nav{display:block;padding-top:3rem;padding-bottom:1rem;overflow-y:auto;flex:1 1 auto}}.site-header{display:flex;min-height:60px;align-items:center}@media (min-width: 50rem){.site-header{height:60px;max-height:60px;border-bottom:1px solid #eeebee}}.site-title{padding-right:1rem;padding-left:1rem;flex-grow:1;display:flex;height:100%;align-items:center;padding-top:.75rem;padding-bottom:.75rem;color:#27262b;font-size:18px !important}@media (min-width: 50rem){.site-title{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-title{font-size:24px !important;line-height:1.25}}@media (min-width: 50rem){.site-title{padding-top:.5rem;padding-bottom:.5rem}}.site-button{display:flex;height:100%;padding:1rem;align-items:center}@media (min-width: 50rem){.site-header .site-button{display:none}}.site-title:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 80%, rgba(235,237,245,0) 100%)}.site-button:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 100%)}body{position:relative;padding-bottom:4rem;overflow-y:scroll}@media (min-width: 50rem){body{position:static;padding-bottom:0}}.site-footer{padding-right:1rem;padding-left:1rem;position:absolute;bottom:0;left:0;padding-top:1rem;padding-bottom:1rem;color:#959396;font-size:11px !important}@media (min-width: 50rem){.site-footer{padding-right:2rem;padding-left:2rem}}@media (min-width: 31.25rem){.site-footer{font-size:12px !important}}@media (min-width: 50rem){.site-footer{position:static;justify-self:end}}.icon{width:1.5rem;height:1.5rem;color:#7253ed}.main-content{line-height:1.6}.main-content ol,.main-content ul,.main-content dl,.main-content pre,.main-content address,.main-content blockquote,.main-content .table-wrapper{margin-top:0.5em}.main-content a{overflow:hidden;text-overflow:ellipsis}.main-content ul,.main-content ol{padding-left:1.5em}.main-content li .highlight{margin-top:.25rem}.main-content ol{list-style-type:none;counter-reset:step-counter}.main-content ol>li{position:relative}.main-content ol>li::before{position:absolute;top:0.2em;left:-1.6em;color:#959396;content:counter(step-counter);counter-increment:step-counter;font-size:12px !important}@media (min-width: 31.25rem){.main-content ol>li::before{font-size:14px !important}}@media (min-width: 31.25rem){.main-content ol>li::before{top:0.11em}}.main-content ol>li ol{counter-reset:sub-counter}.main-content ol>li ol>li::before{content:counter(sub-counter,lower-alpha);counter-increment:sub-counter}.main-content ul{list-style:none}.main-content ul>li::before{position:absolute;margin-left:-1.4em;color:#959396;content:"•"}.main-content .task-list-item::before{content:""}.main-content .task-list-item-checkbox{margin-right:0.6em;margin-left:-1.4em}.main-content hr+*{margin-top:0}.main-content h1:first-of-type{margin-top:0.5em}.main-content dl{display:grid;grid-template:auto / 10em 1fr}.main-content dt,.main-content dd{margin:0.25em 0}.main-content dt{grid-column:1;font-weight:500;text-align:right}.main-content dt::after{content:":"}.main-content dd{grid-column:2;margin-bottom:0;margin-left:1em}.main-content dd blockquote:first-child,.main-content dd div:first-child,.main-content dd dl:first-child,.main-content dd dt:first-child,.main-content dd h1:first-child,.main-content dd h2:first-child,.main-content dd h3:first-child,.main-content dd h4:first-child,.main-content dd h5:first-child,.main-content dd h6:first-child,.main-content dd li:first-child,.main-content dd ol:first-child,.main-content dd p:first-child,.main-content dd pre:first-child,.main-content dd table:first-child,.main-content dd ul:first-child,.main-content dd .table-wrapper:first-child{margin-top:0}.main-content dd dl:first-child dt:first-child,.main-content dd dl:first-child dd:nth-child(2),.main-content ol dl:first-child dt:first-child,.main-content ol dl:first-child dd:nth-child(2),.main-content ul dl:first-child dt:first-child,.main-content ul dl:first-child dd:nth-child(2){margin-top:0}.main-content .anchor-heading{position:absolute;right:-1rem;width:1.5rem;height:100%;padding-right:.25rem;padding-left:.25rem;overflow:visible}@media (min-width: 50rem){.main-content .anchor-heading{right:auto;left:-1.5rem}}.main-content .anchor-heading svg{display:inline-block;width:100%;height:100%;color:#7253ed;visibility:hidden}.main-content .anchor-heading:hover svg,.main-content .anchor-heading:focus svg,.main-content h1:hover>.anchor-heading svg,.main-content h2:hover>.anchor-heading svg,.main-content h3:hover>.anchor-heading svg,.main-content h4:hover>.anchor-heading svg,.main-content h5:hover>.anchor-heading svg,.main-content h6:hover>.anchor-heading svg{visibility:visible}.main-content summary{cursor:pointer}.main-content h1,.main-content h2,.main-content h3,.main-content h4,.main-content h5,.main-content h6,.main-content #toctitle{position:relative;margin-top:1.5em;margin-bottom:0.25em}.main-content h1+table,.main-content h1+.table-wrapper,.main-content h1+.code-example,.main-content h1+.highlighter-rouge,.main-content h1+.sectionbody .listingblock,.main-content h2+table,.main-content h2+.table-wrapper,.main-content h2+.code-example,.main-content h2+.highlighter-rouge,.main-content h2+.sectionbody .listingblock,.main-content h3+table,.main-content h3+.table-wrapper,.main-content h3+.code-example,.main-content h3+.highlighter-rouge,.main-content h3+.sectionbody .listingblock,.main-content h4+table,.main-content h4+.table-wrapper,.main-content h4+.code-example,.main-content h4+.highlighter-rouge,.main-content h4+.sectionbody .listingblock,.main-content h5+table,.main-content h5+.table-wrapper,.main-content h5+.code-example,.main-content h5+.highlighter-rouge,.main-content h5+.sectionbody .listingblock,.main-content h6+table,.main-content h6+.table-wrapper,.main-content h6+.code-example,.main-content h6+.highlighter-rouge,.main-content h6+.sectionbody .listingblock,.main-content #toctitle+table,.main-content #toctitle+.table-wrapper,.main-content #toctitle+.code-example,.main-content #toctitle+.highlighter-rouge,.main-content #toctitle+.sectionbody .listingblock{margin-top:1em}.main-content h1+p:not(.label),.main-content h2+p:not(.label),.main-content h3+p:not(.label),.main-content h4+p:not(.label),.main-content h5+p:not(.label),.main-content h6+p:not(.label),.main-content #toctitle+p:not(.label){margin-top:0}.main-content>h1:first-child,.main-content>h2:first-child,.main-content>h3:first-child,.main-content>h4:first-child,.main-content>h5:first-child,.main-content>h6:first-child,.main-content>.sect1:first-child>h2,.main-content>.sect2:first-child>h3,.main-content>.sect3:first-child>h4,.main-content>.sect4:first-child>h5,.main-content>.sect5:first-child>h6{margin-top:.5rem}.nav-list{padding:0;margin-top:0;margin-bottom:0;list-style:none}.nav-list .nav-list-item{font-size:14px !important;position:relative;margin:0}@media (min-width: 31.25rem){.nav-list .nav-list-item{font-size:16px !important}}@media (min-width: 50rem){.nav-list .nav-list-item{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.nav-list .nav-list-item{font-size:14px !important}}.nav-list .nav-list-item .nav-list-link{display:block;min-height:3rem;padding-top:.25rem;padding-bottom:.25rem;line-height:2.5rem;padding-right:3rem;padding-left:1rem}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-link{min-height:2rem;line-height:1.5rem;padding-right:2rem;padding-left:2rem}}.nav-list .nav-list-item .nav-list-link.external>svg{width:1rem;height:1rem;vertical-align:text-bottom}.nav-list .nav-list-item .nav-list-link.active{font-weight:600;text-decoration:none}.nav-list .nav-list-item .nav-list-link:hover,.nav-list .nav-list-item .nav-list-link.active{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 80%, rgba(235,237,245,0) 100%)}.nav-list .nav-list-item .nav-list-expander{position:absolute;right:0;width:3rem;height:3rem;padding:.75rem;color:#7253ed}@media (min-width: 50rem){.nav-list .nav-list-item .nav-list-expander{width:2rem;height:2rem;padding:.5rem}}.nav-list .nav-list-item .nav-list-expander:hover{background-image:linear-gradient(-90deg, #ebedf5 0%, rgba(235,237,245,0.8) 100%)}.nav-list .nav-list-item .nav-list-expander svg{transform:rotate(90deg)}.nav-list .nav-list-item>.nav-list{display:none;padding-left:.75rem;list-style:none}.nav-list .nav-list-item>.nav-list .nav-list-item{position:relative}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-link{color:#5c5962}.nav-list .nav-list-item>.nav-list .nav-list-item .nav-list-expander{color:#5c5962}.nav-list .nav-list-item.active>.nav-list-expander svg{transform:rotate(-90deg)}.nav-list .nav-list-item.active>.nav-list{display:block}.nav-category{padding:.5rem 1rem;font-weight:600;text-align:start;text-transform:uppercase;border-bottom:1px solid #eeebee;font-size:11px !important}@media (min-width: 31.25rem){.nav-category{font-size:12px !important}}@media (min-width: 50rem){.nav-category{padding:.5rem 2rem;margin-top:1rem;text-align:start}.nav-category:first-child{margin-top:0}}.nav-list.nav-category-list>.nav-list-item{margin:0}.nav-list.nav-category-list>.nav-list-item>.nav-list{padding:0}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-link{color:#7253ed}.nav-list.nav-category-list>.nav-list-item>.nav-list>.nav-list-item>.nav-list-expander{color:#7253ed}.aux-nav{height:100%;overflow-x:auto;font-size:11px !important}@media (min-width: 31.25rem){.aux-nav{font-size:12px !important}}.aux-nav .aux-nav-list{display:flex;height:100%;padding:0;margin:0;list-style:none}.aux-nav .aux-nav-list-item{display:inline-block;height:100%;padding:0;margin:0}@media (min-width: 50rem){.aux-nav{padding-right:1rem}}@media (min-width: 50rem){.breadcrumb-nav{margin-top:-1rem}}.breadcrumb-nav-list{padding-left:0;margin-bottom:.75rem;list-style:none}.breadcrumb-nav-list-item{display:table-cell;font-size:11px !important}@media (min-width: 31.25rem){.breadcrumb-nav-list-item{font-size:12px !important}}.breadcrumb-nav-list-item::before{display:none}.breadcrumb-nav-list-item::after{display:inline-block;margin-right:.5rem;margin-left:.5rem;color:#959396;content:"/"}.breadcrumb-nav-list-item:last-child::after{content:""}h1,.text-alpha{font-size:32px !important;line-height:1.25;font-weight:300}@media (min-width: 31.25rem){h1,.text-alpha{font-size:36px !important}}h2,.text-beta,#toctitle{font-size:18px !important}@media (min-width: 31.25rem){h2,.text-beta,#toctitle{font-size:24px !important;line-height:1.25}}h3,.text-gamma{font-size:16px !important}@media (min-width: 31.25rem){h3,.text-gamma{font-size:18px !important}}h4,.text-delta{font-size:11px !important;font-weight:400;text-transform:uppercase;letter-spacing:0.1em}@media (min-width: 31.25rem){h4,.text-delta{font-size:12px !important}}h4 code{text-transform:none}h5,.text-epsilon{font-size:12px !important}@media (min-width: 31.25rem){h5,.text-epsilon{font-size:14px !important}}h6,.text-zeta{font-size:11px !important}@media (min-width: 31.25rem){h6,.text-zeta{font-size:12px !important}}.text-small{font-size:11px !important}@media (min-width: 31.25rem){.text-small{font-size:12px !important}}.text-mono{font-family:"SFMono-Regular",menlo,consolas,monospace !important}.text-left{text-align:left !important}.text-center{text-align:center !important}.text-right{text-align:right !important}.label,.label-blue{display:inline-block;padding:0.16em 0.56em;margin-right:.5rem;margin-left:.5rem;color:#fff;text-transform:uppercase;vertical-align:middle;background-color:#2869e6;font-size:11px !important;border-radius:12px}@media (min-width: 31.25rem){.label,.label-blue{font-size:12px !important}}.label-green{background-color:#009c7b}.label-purple{background-color:#5e41d0}.label-red{background-color:#e94c4c}.label-yellow{color:#44434d;background-color:#f7d12e}.btn{display:inline-block;box-sizing:border-box;padding:0.3em 1em;margin:0;font-family:inherit;font-size:inherit;font-weight:500;line-height:1.5;color:#7253ed;text-decoration:none;vertical-align:baseline;cursor:pointer;background-color:#f7f7f7;border-width:0;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);appearance:none}.btn:focus{text-decoration:none;outline:none;box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:focus:hover,.btn.selected:focus{box-shadow:0 0 0 3px rgba(0,0,255,0.25)}.btn:hover,.btn.zeroclipboard-is-hover{color:#6a4aec}.btn:hover,.btn:active,.btn.zeroclipboard-is-hover,.btn.zeroclipboard-is-active{text-decoration:none;background-color:#f4f4f4}.btn:active,.btn.selected,.btn.zeroclipboard-is-active{background-color:#efefef;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn.selected:hover{background-color:#cfcfcf}.btn:disabled,.btn:disabled:hover,.btn.disabled,.btn.disabled:hover{color:rgba(102,102,102,0.5);cursor:default;background-color:rgba(229,229,229,0.5);background-image:none;box-shadow:none}.btn-outline{color:#7253ed;background:transparent;box-shadow:inset 0 0 0 2px #e6e1e8}.btn-outline:hover,.btn-outline:active,.btn-outline.zeroclipboard-is-hover,.btn-outline.zeroclipboard-is-active{color:#6341eb;text-decoration:none;background-color:transparent;box-shadow:inset 0 0 0 3px #e6e1e8}.btn-outline:focus{text-decoration:none;outline:none;box-shadow:inset 0 0 0 2px #5c5962,0 0 0 3px rgba(0,0,255,0.25)}.btn-outline:focus:hover,.btn-outline.selected:focus{box-shadow:inset 0 0 0 2px #5c5962}.btn-primary{color:#fff;background-color:#5739ce;background-image:linear-gradient(#6f55d5, #5739ce);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-primary:hover,.btn-primary.zeroclipboard-is-hover{color:#fff;background-color:#5132cb;background-image:linear-gradient(#6549d2,#5132cb)}.btn-primary:active,.btn-primary.selected,.btn-primary.zeroclipboard-is-active{background-color:#4f31c6;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-primary.selected:hover{background-color:#472cb2}.btn-purple{color:#fff;background-color:#5739ce;background-image:linear-gradient(#6f55d5, #5739ce);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-purple:hover,.btn-purple.zeroclipboard-is-hover{color:#fff;background-color:#5132cb;background-image:linear-gradient(#6549d2,#5132cb)}.btn-purple:active,.btn-purple.selected,.btn-purple.zeroclipboard-is-active{background-color:#4f31c6;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-purple.selected:hover{background-color:#472cb2}.btn-blue{color:#fff;background-color:#227efa;background-image:linear-gradient(#4593fb, #227efa);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-blue:hover,.btn-blue.zeroclipboard-is-hover{color:#fff;background-color:#1878fa;background-image:linear-gradient(#368afa,#1878fa)}.btn-blue:active,.btn-blue.selected,.btn-blue.zeroclipboard-is-active{background-color:#1375f9;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-blue.selected:hover{background-color:#0669ed}.btn-green{color:#fff;background-color:#10ac7d;background-image:linear-gradient(#13cc95, #10ac7d);box-shadow:0 1px 3px rgba(0,0,0,0.25),0 4px 10px rgba(0,0,0,0.12)}.btn-green:hover,.btn-green.zeroclipboard-is-hover{color:#fff;background-color:#0fa276;background-image:linear-gradient(#12be8b,#0fa276)}.btn-green:active,.btn-green.selected,.btn-green.zeroclipboard-is-active{background-color:#0f9e73;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,0.15)}.btn-green.selected:hover{background-color:#0d8662}.search{position:relative;z-index:2;flex-grow:1;height:4rem;padding:.5rem;transition:padding linear 200ms}@media (min-width: 50rem){.search{position:relative !important;width:auto !important;height:100% !important;padding:0;transition:none}}.search-input-wrap{position:relative;z-index:1;height:3rem;overflow:hidden;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);transition:height linear 200ms}@media (min-width: 50rem){.search-input-wrap{position:absolute;width:100%;max-width:536px;height:100% !important;border-radius:0;box-shadow:none;transition:width ease 400ms}}.search-input{position:absolute;width:100%;height:100%;padding:.5rem 1rem .5rem 2.5rem;font-size:16px;color:#5c5962;background-color:#fff;border-top:0;border-right:0;border-bottom:0;border-left:0;border-radius:0}@media (min-width: 50rem){.search-input{padding:.5rem 1rem .5rem 3.5rem;font-size:14px;background-color:#fff;transition:padding-left linear 200ms}}.search-input:focus{outline:0}.search-input:focus+.search-label .search-icon{color:#7253ed}.search-label{position:absolute;display:flex;height:100%;padding-left:1rem}@media (min-width: 50rem){.search-label{padding-left:2rem;transition:padding-left linear 200ms}}.search-label .search-icon{width:1.2rem;height:1.2rem;align-self:center;color:#959396}.search-results{position:absolute;left:0;display:none;width:100%;max-height:calc(100% - 4rem);overflow-y:auto;background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}@media (min-width: 50rem){.search-results{top:100%;width:536px;max-height:calc(100vh - 200%) !important}}.search-results-list{padding-left:0;margin-bottom:.25rem;list-style:none;font-size:14px !important}@media (min-width: 31.25rem){.search-results-list{font-size:16px !important}}@media (min-width: 50rem){.search-results-list{font-size:12px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-results-list{font-size:14px !important}}.search-results-list-item{padding:0;margin:0}.search-result{display:block;padding:.25rem .75rem}.search-result:hover,.search-result.active{background-color:#ebedf5}.search-result-title{display:block;padding-top:.5rem;padding-bottom:.5rem}@media (min-width: 31.25rem){.search-result-title{display:inline-block;width:40%;padding-right:.5rem;vertical-align:top}}.search-result-doc{display:flex;align-items:center;word-wrap:break-word}.search-result-doc.search-result-doc-parent{opacity:0.5;font-size:12px !important}@media (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:14px !important}}@media (min-width: 50rem){.search-result-doc.search-result-doc-parent{font-size:11px !important}}@media (min-width: 50rem) and (min-width: 31.25rem){.search-result-doc.search-result-doc-parent{font-size:12px !important}}.search-result-doc .search-result-icon{width:1rem;height:1rem;margin-right:.5rem;color:#7253ed;flex-shrink:0}.search-result-doc .search-result-doc-title{overflow:auto}.search-result-section{margin-left:1.5rem;word-wrap:break-word}.search-result-rel-url{display:block;margin-left:1.5rem;overflow:hidden;color:#959396;text-overflow:ellipsis;white-space:nowrap;font-size:9px !important}@media (min-width: 31.25rem){.search-result-rel-url{font-size:10px !important}}.search-result-previews{display:block;padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;margin-left:.5rem;color:#959396;word-wrap:break-word;border-left:1px solid;border-left-color:#eeebee;font-size:11px !important}@media (min-width: 31.25rem){.search-result-previews{font-size:12px !important}}@media (min-width: 31.25rem){.search-result-previews{display:inline-block;width:60%;padding-left:.5rem;margin-left:0;vertical-align:top}}.search-result-preview+.search-result-preview{margin-top:.25rem}.search-result-highlight{font-weight:bold}.search-no-result{padding:.5rem .75rem;font-size:12px !important}@media (min-width: 31.25rem){.search-no-result{font-size:14px !important}}.search-button{position:fixed;right:1rem;bottom:1rem;display:flex;width:3.5rem;height:3.5rem;background-color:#fff;border:1px solid rgba(114,83,237,0.3);border-radius:1.75rem;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08);align-items:center;justify-content:center}.search-overlay{position:fixed;top:0;left:0;z-index:1;width:0;height:0;background-color:rgba(0,0,0,0.3);opacity:0;transition:opacity ease 400ms,width 0s 400ms,height 0s 400ms}.search-active .search{position:fixed;top:0;left:0;width:100%;height:100%;padding:0}.search-active .search-input-wrap{height:4rem;border-radius:0}@media (min-width: 50rem){.search-active .search-input-wrap{width:536px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}}.search-active .search-input{background-color:#fff}@media (min-width: 50rem){.search-active .search-input{padding-left:2.3rem}}@media (min-width: 50rem){.search-active .search-label{padding-left:0.6rem}}.search-active .search-results{display:block}.search-active .search-overlay{width:100%;height:100%;opacity:1;transition:opacity ease 400ms,width 0s,height 0s}@media (min-width: 50rem){.search-active .main{position:fixed;right:0;left:0}}.search-active .main-header{padding-top:4rem}@media (min-width: 50rem){.search-active .main-header{padding-top:0}}.table-wrapper{display:block;width:100%;max-width:100%;margin-bottom:1.5rem;overflow-x:auto;border-radius:4px;box-shadow:0 1px 2px rgba(0,0,0,0.12),0 3px 10px rgba(0,0,0,0.08)}table{display:table;min-width:100%;border-collapse:separate}th,td{font-size:12px !important;min-width:120px;padding:.5rem .75rem;background-color:#fff;border-bottom:1px solid rgba(238,235,238,0.5);border-left:1px solid #eeebee}@media (min-width: 31.25rem){th,td{font-size:14px !important}}th:first-of-type,td:first-of-type{border-left:0}tbody tr:last-of-type th,tbody tr:last-of-type td{border-bottom:0}tbody tr:last-of-type td{padding-bottom:.75rem}thead th{border-bottom:1px solid #eeebee}:not(pre,figure)>code{padding:0.2em 0.15em;font-weight:400;background-color:#f5f6fa;border:1px solid #eeebee;border-radius:4px}a:visited code{border-color:#eeebee}div.highlighter-rouge,div.listingblock>div.content,figure.highlight{margin-top:0;margin-bottom:.75rem;background-color:#f5f6fa;border-radius:4px;box-shadow:none;-webkit-overflow-scrolling:touch;position:relative;padding:0}div.highlighter-rouge>button,div.listingblock>div.content>button,figure.highlight>button{width:.75rem;opacity:0;position:absolute;top:0;right:0;border:.75rem solid #f5f6fa;background-color:#f5f6fa;color:#5c5962;box-sizing:content-box}div.highlighter-rouge>button svg,div.listingblock>div.content>button svg,figure.highlight>button svg{fill:#5c5962}div.highlighter-rouge>button:active,div.listingblock>div.content>button:active,figure.highlight>button:active{text-decoration:none;outline:none;opacity:1}div.highlighter-rouge>button:focus,div.listingblock>div.content>button:focus,figure.highlight>button:focus{opacity:1}div.highlighter-rouge:hover>button,div.listingblock>div.content:hover>button,figure.highlight:hover>button{cursor:copy;opacity:1}div.highlighter-rouge div.highlight{overflow-x:auto;padding:.75rem;margin:0;border:0}div.highlighter-rouge pre.highlight,div.highlighter-rouge code{padding:0;margin:0;border:0}div.listingblock{margin-top:0;margin-bottom:.75rem}div.listingblock div.content{overflow-x:auto;padding:.75rem;margin:0;border:0}div.listingblock div.content>pre,div.listingblock code{padding:0;margin:0;border:0}figure.highlight pre,figure.highlight :not(pre)>code{overflow-x:auto;padding:.75rem;margin:0;border:0}.highlight .table-wrapper{padding:.75rem 0;margin:0;border:0;box-shadow:none}.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:11px !important;min-width:0;padding:0;background-color:#f5f6fa;border:0}@media (min-width: 31.25rem){.highlight .table-wrapper td,.highlight .table-wrapper pre{font-size:12px !important}}.highlight .table-wrapper td.gl{width:1em;padding-right:.75rem;padding-left:.75rem}.highlight .table-wrapper pre{margin:0;line-height:2}.code-example,.listingblock>.title{padding:.75rem;margin-bottom:.75rem;overflow:auto;border:1px solid #eeebee;border-radius:4px}.code-example+.highlighter-rouge,.code-example+.sectionbody .listingblock,.code-example+.content,.code-example+figure.highlight,.listingblock>.title+.highlighter-rouge,.listingblock>.title+.sectionbody .listingblock,.listingblock>.title+.content,.listingblock>.title+figure.highlight{position:relative;margin-top:-1rem;border-right:1px solid #eeebee;border-bottom:1px solid #eeebee;border-left:1px solid #eeebee;border-top-left-radius:0;border-top-right-radius:0}code.language-mermaid{padding:0;background-color:inherit;border:0}.highlight,pre.highlight{background:#f5f6fa;color:#5c5962}.highlight pre{background:#f5f6fa}.text-grey-dk-000{color:#959396 !important}.text-grey-dk-100{color:#5c5962 !important}.text-grey-dk-200{color:#44434d !important}.text-grey-dk-250{color:#302d36 !important}.text-grey-dk-300{color:#27262b !important}.text-grey-lt-000{color:#f5f6fa !important}.text-grey-lt-100{color:#eeebee !important}.text-grey-lt-200{color:#ecebed !important}.text-grey-lt-300{color:#e6e1e8 !important}.text-blue-000{color:#2c84fa !important}.text-blue-100{color:#2869e6 !important}.text-blue-200{color:#264caf !important}.text-blue-300{color:#183385 !important}.text-green-000{color:#41d693 !important}.text-green-100{color:#11b584 !important}.text-green-200{color:#009c7b !important}.text-green-300{color:#026e57 !important}.text-purple-000{color:#7253ed !important}.text-purple-100{color:#5e41d0 !important}.text-purple-200{color:#4e26af !important}.text-purple-300{color:#381885 !important}.text-yellow-000{color:#ffeb82 !important}.text-yellow-100{color:#fadf50 !important}.text-yellow-200{color:#f7d12e !important}.text-yellow-300{color:#e7af06 !important}.text-red-000{color:#f77e7e !important}.text-red-100{color:#f96e65 !important}.text-red-200{color:#e94c4c !important}.text-red-300{color:#dd2e2e !important}.bg-grey-dk-000{background-color:#959396 !important}.bg-grey-dk-100{background-color:#5c5962 !important}.bg-grey-dk-200{background-color:#44434d !important}.bg-grey-dk-250{background-color:#302d36 !important}.bg-grey-dk-300{background-color:#27262b !important}.bg-grey-lt-000{background-color:#f5f6fa !important}.bg-grey-lt-100{background-color:#eeebee !important}.bg-grey-lt-200{background-color:#ecebed !important}.bg-grey-lt-300{background-color:#e6e1e8 !important}.bg-blue-000{background-color:#2c84fa !important}.bg-blue-100{background-color:#2869e6 !important}.bg-blue-200{background-color:#264caf !important}.bg-blue-300{background-color:#183385 !important}.bg-green-000{background-color:#41d693 !important}.bg-green-100{background-color:#11b584 !important}.bg-green-200{background-color:#009c7b !important}.bg-green-300{background-color:#026e57 !important}.bg-purple-000{background-color:#7253ed !important}.bg-purple-100{background-color:#5e41d0 !important}.bg-purple-200{background-color:#4e26af !important}.bg-purple-300{background-color:#381885 !important}.bg-yellow-000{background-color:#ffeb82 !important}.bg-yellow-100{background-color:#fadf50 !important}.bg-yellow-200{background-color:#f7d12e !important}.bg-yellow-300{background-color:#e7af06 !important}.bg-red-000{background-color:#f77e7e !important}.bg-red-100{background-color:#f96e65 !important}.bg-red-200{background-color:#e94c4c !important}.bg-red-300{background-color:#dd2e2e !important}.d-block{display:block !important}.d-flex{display:flex !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-none{display:none !important}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 20rem){.d-xs-block{display:block !important}.d-xs-flex{display:flex !important}.d-xs-inline{display:inline !important}.d-xs-inline-block{display:inline-block !important}.d-xs-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 31.25rem){.d-sm-block{display:block !important}.d-sm-flex{display:flex !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 50rem){.d-md-block{display:block !important}.d-md-flex{display:flex !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 66.5rem){.d-lg-block{display:block !important}.d-lg-flex{display:flex !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}@media (min-width: 87.5rem){.d-xl-block{display:block !important}.d-xl-flex{display:flex !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-none{display:none !important}}.float-left{float:left !important}.float-right{float:right !important}.flex-justify-start{justify-content:flex-start !important}.flex-justify-end{justify-content:flex-end !important}.flex-justify-between{justify-content:space-between !important}.flex-justify-around{justify-content:space-around !important}.v-align-baseline{vertical-align:baseline !important}.v-align-bottom{vertical-align:bottom !important}.v-align-middle{vertical-align:middle !important}.v-align-text-bottom{vertical-align:text-bottom !important}.v-align-text-top{vertical-align:text-top !important}.v-align-top{vertical-align:top !important}.fs-1{font-size:9px !important}@media (min-width: 31.25rem){.fs-1{font-size:10px !important}}.fs-2{font-size:11px !important}@media (min-width: 31.25rem){.fs-2{font-size:12px !important}}.fs-3{font-size:12px !important}@media (min-width: 31.25rem){.fs-3{font-size:14px !important}}.fs-4{font-size:14px !important}@media (min-width: 31.25rem){.fs-4{font-size:16px !important}}.fs-5{font-size:16px !important}@media (min-width: 31.25rem){.fs-5{font-size:18px !important}}.fs-6{font-size:18px !important}@media (min-width: 31.25rem){.fs-6{font-size:24px !important;line-height:1.25}}.fs-7{font-size:24px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-7{font-size:32px !important}}.fs-8{font-size:32px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-8{font-size:36px !important}}.fs-9{font-size:36px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-9{font-size:42px !important}}.fs-10{font-size:42px !important;line-height:1.25}@media (min-width: 31.25rem){.fs-10{font-size:48px !important}}.fw-300{font-weight:300 !important}.fw-400{font-weight:400 !important}.fw-500{font-weight:500 !important}.fw-700{font-weight:700 !important}.lh-0{line-height:0 !important}.lh-default{line-height:1.4}.lh-tight{line-height:1.25}.ls-5{letter-spacing:0.05em !important}.ls-10{letter-spacing:0.1em !important}.ls-0{letter-spacing:0 !important}.text-uppercase{text-transform:uppercase !important}.list-style-none{padding:0 !important;margin:0 !important;list-style:none !important}.list-style-none li::before{display:none !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-0{margin-right:-0 !important;margin-left:-0 !important}.mx-0-auto{margin-right:auto !important;margin-left:auto !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-1{margin-right:-.25rem !important;margin-left:-.25rem !important}.mx-1-auto{margin-right:auto !important;margin-left:auto !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-2{margin-right:-.5rem !important;margin-left:-.5rem !important}.mx-2-auto{margin-right:auto !important;margin-left:auto !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-3{margin-right:-.75rem !important;margin-left:-.75rem !important}.mx-3-auto{margin-right:auto !important;margin-left:auto !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-right:1rem !important;margin-left:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-4{margin-right:-1rem !important;margin-left:-1rem !important}.mx-4-auto{margin-right:auto !important;margin-left:auto !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}.mx-5-auto{margin-right:auto !important;margin-left:auto !important}.m-6{margin:2rem !important}.mt-6{margin-top:2rem !important}.mr-6{margin-right:2rem !important}.mb-6{margin-bottom:2rem !important}.ml-6{margin-left:2rem !important}.mx-6{margin-right:2rem !important;margin-left:2rem !important}.my-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-6{margin-right:-2rem !important;margin-left:-2rem !important}.mx-6-auto{margin-right:auto !important;margin-left:auto !important}.m-7{margin:2.5rem !important}.mt-7{margin-top:2.5rem !important}.mr-7{margin-right:2.5rem !important}.mb-7{margin-bottom:2.5rem !important}.ml-7{margin-left:2.5rem !important}.mx-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}.mx-7-auto{margin-right:auto !important;margin-left:auto !important}.m-8{margin:3rem !important}.mt-8{margin-top:3rem !important}.mr-8{margin-right:3rem !important}.mb-8{margin-bottom:3rem !important}.ml-8{margin-left:3rem !important}.mx-8{margin-right:3rem !important;margin-left:3rem !important}.my-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-8{margin-right:-3rem !important;margin-left:-3rem !important}.mx-8-auto{margin-right:auto !important;margin-left:auto !important}.m-9{margin:3.5rem !important}.mt-9{margin-top:3.5rem !important}.mr-9{margin-right:3.5rem !important}.mb-9{margin-bottom:3.5rem !important}.ml-9{margin-left:3.5rem !important}.mx-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}.mx-9-auto{margin-right:auto !important;margin-left:auto !important}.m-10{margin:4rem !important}.mt-10{margin-top:4rem !important}.mr-10{margin-right:4rem !important}.mb-10{margin-bottom:4rem !important}.ml-10{margin-left:4rem !important}.mx-10{margin-right:4rem !important;margin-left:4rem !important}.my-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-10{margin-right:-4rem !important;margin-left:-4rem !important}.mx-10-auto{margin-right:auto !important;margin-left:auto !important}@media (min-width: 20rem){.m-xs-0{margin:0 !important}.mt-xs-0{margin-top:0 !important}.mr-xs-0{margin-right:0 !important}.mb-xs-0{margin-bottom:0 !important}.ml-xs-0{margin-left:0 !important}.mx-xs-0{margin-right:0 !important;margin-left:0 !important}.my-xs-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xs-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 20rem){.m-xs-1{margin:.25rem !important}.mt-xs-1{margin-top:.25rem !important}.mr-xs-1{margin-right:.25rem !important}.mb-xs-1{margin-bottom:.25rem !important}.ml-xs-1{margin-left:.25rem !important}.mx-xs-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xs-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xs-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 20rem){.m-xs-2{margin:.5rem !important}.mt-xs-2{margin-top:.5rem !important}.mr-xs-2{margin-right:.5rem !important}.mb-xs-2{margin-bottom:.5rem !important}.ml-xs-2{margin-left:.5rem !important}.mx-xs-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xs-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xs-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 20rem){.m-xs-3{margin:.75rem !important}.mt-xs-3{margin-top:.75rem !important}.mr-xs-3{margin-right:.75rem !important}.mb-xs-3{margin-bottom:.75rem !important}.ml-xs-3{margin-left:.75rem !important}.mx-xs-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xs-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xs-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 20rem){.m-xs-4{margin:1rem !important}.mt-xs-4{margin-top:1rem !important}.mr-xs-4{margin-right:1rem !important}.mb-xs-4{margin-bottom:1rem !important}.ml-xs-4{margin-left:1rem !important}.mx-xs-4{margin-right:1rem !important;margin-left:1rem !important}.my-xs-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xs-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 20rem){.m-xs-5{margin:1.5rem !important}.mt-xs-5{margin-top:1.5rem !important}.mr-xs-5{margin-right:1.5rem !important}.mb-xs-5{margin-bottom:1.5rem !important}.ml-xs-5{margin-left:1.5rem !important}.mx-xs-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xs-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xs-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 20rem){.m-xs-6{margin:2rem !important}.mt-xs-6{margin-top:2rem !important}.mr-xs-6{margin-right:2rem !important}.mb-xs-6{margin-bottom:2rem !important}.ml-xs-6{margin-left:2rem !important}.mx-xs-6{margin-right:2rem !important;margin-left:2rem !important}.my-xs-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xs-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 20rem){.m-xs-7{margin:2.5rem !important}.mt-xs-7{margin-top:2.5rem !important}.mr-xs-7{margin-right:2.5rem !important}.mb-xs-7{margin-bottom:2.5rem !important}.ml-xs-7{margin-left:2.5rem !important}.mx-xs-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xs-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xs-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 20rem){.m-xs-8{margin:3rem !important}.mt-xs-8{margin-top:3rem !important}.mr-xs-8{margin-right:3rem !important}.mb-xs-8{margin-bottom:3rem !important}.ml-xs-8{margin-left:3rem !important}.mx-xs-8{margin-right:3rem !important;margin-left:3rem !important}.my-xs-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xs-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 20rem){.m-xs-9{margin:3.5rem !important}.mt-xs-9{margin-top:3.5rem !important}.mr-xs-9{margin-right:3.5rem !important}.mb-xs-9{margin-bottom:3.5rem !important}.ml-xs-9{margin-left:3.5rem !important}.mx-xs-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xs-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xs-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 20rem){.m-xs-10{margin:4rem !important}.mt-xs-10{margin-top:4rem !important}.mr-xs-10{margin-right:4rem !important}.mb-xs-10{margin-bottom:4rem !important}.ml-xs-10{margin-left:4rem !important}.mx-xs-10{margin-right:4rem !important;margin-left:4rem !important}.my-xs-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xs-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 31.25rem){.m-sm-0{margin:0 !important}.mt-sm-0{margin-top:0 !important}.mr-sm-0{margin-right:0 !important}.mb-sm-0{margin-bottom:0 !important}.ml-sm-0{margin-left:0 !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-sm-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 31.25rem){.m-sm-1{margin:.25rem !important}.mt-sm-1{margin-top:.25rem !important}.mr-sm-1{margin-right:.25rem !important}.mb-sm-1{margin-bottom:.25rem !important}.ml-sm-1{margin-left:.25rem !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-sm-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 31.25rem){.m-sm-2{margin:.5rem !important}.mt-sm-2{margin-top:.5rem !important}.mr-sm-2{margin-right:.5rem !important}.mb-sm-2{margin-bottom:.5rem !important}.ml-sm-2{margin-left:.5rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-sm-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 31.25rem){.m-sm-3{margin:.75rem !important}.mt-sm-3{margin-top:.75rem !important}.mr-sm-3{margin-right:.75rem !important}.mb-sm-3{margin-bottom:.75rem !important}.ml-sm-3{margin-left:.75rem !important}.mx-sm-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-sm-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-sm-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 31.25rem){.m-sm-4{margin:1rem !important}.mt-sm-4{margin-top:1rem !important}.mr-sm-4{margin-right:1rem !important}.mb-sm-4{margin-bottom:1rem !important}.ml-sm-4{margin-left:1rem !important}.mx-sm-4{margin-right:1rem !important;margin-left:1rem !important}.my-sm-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-sm-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 31.25rem){.m-sm-5{margin:1.5rem !important}.mt-sm-5{margin-top:1.5rem !important}.mr-sm-5{margin-right:1.5rem !important}.mb-sm-5{margin-bottom:1.5rem !important}.ml-sm-5{margin-left:1.5rem !important}.mx-sm-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-sm-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-sm-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 31.25rem){.m-sm-6{margin:2rem !important}.mt-sm-6{margin-top:2rem !important}.mr-sm-6{margin-right:2rem !important}.mb-sm-6{margin-bottom:2rem !important}.ml-sm-6{margin-left:2rem !important}.mx-sm-6{margin-right:2rem !important;margin-left:2rem !important}.my-sm-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-sm-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 31.25rem){.m-sm-7{margin:2.5rem !important}.mt-sm-7{margin-top:2.5rem !important}.mr-sm-7{margin-right:2.5rem !important}.mb-sm-7{margin-bottom:2.5rem !important}.ml-sm-7{margin-left:2.5rem !important}.mx-sm-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-sm-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-sm-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 31.25rem){.m-sm-8{margin:3rem !important}.mt-sm-8{margin-top:3rem !important}.mr-sm-8{margin-right:3rem !important}.mb-sm-8{margin-bottom:3rem !important}.ml-sm-8{margin-left:3rem !important}.mx-sm-8{margin-right:3rem !important;margin-left:3rem !important}.my-sm-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-sm-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 31.25rem){.m-sm-9{margin:3.5rem !important}.mt-sm-9{margin-top:3.5rem !important}.mr-sm-9{margin-right:3.5rem !important}.mb-sm-9{margin-bottom:3.5rem !important}.ml-sm-9{margin-left:3.5rem !important}.mx-sm-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-sm-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-sm-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 31.25rem){.m-sm-10{margin:4rem !important}.mt-sm-10{margin-top:4rem !important}.mr-sm-10{margin-right:4rem !important}.mb-sm-10{margin-bottom:4rem !important}.ml-sm-10{margin-left:4rem !important}.mx-sm-10{margin-right:4rem !important;margin-left:4rem !important}.my-sm-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-sm-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 50rem){.m-md-0{margin:0 !important}.mt-md-0{margin-top:0 !important}.mr-md-0{margin-right:0 !important}.mb-md-0{margin-bottom:0 !important}.ml-md-0{margin-left:0 !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-md-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 50rem){.m-md-1{margin:.25rem !important}.mt-md-1{margin-top:.25rem !important}.mr-md-1{margin-right:.25rem !important}.mb-md-1{margin-bottom:.25rem !important}.ml-md-1{margin-left:.25rem !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-md-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 50rem){.m-md-2{margin:.5rem !important}.mt-md-2{margin-top:.5rem !important}.mr-md-2{margin-right:.5rem !important}.mb-md-2{margin-bottom:.5rem !important}.ml-md-2{margin-left:.5rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-md-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 50rem){.m-md-3{margin:.75rem !important}.mt-md-3{margin-top:.75rem !important}.mr-md-3{margin-right:.75rem !important}.mb-md-3{margin-bottom:.75rem !important}.ml-md-3{margin-left:.75rem !important}.mx-md-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-md-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-md-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 50rem){.m-md-4{margin:1rem !important}.mt-md-4{margin-top:1rem !important}.mr-md-4{margin-right:1rem !important}.mb-md-4{margin-bottom:1rem !important}.ml-md-4{margin-left:1rem !important}.mx-md-4{margin-right:1rem !important;margin-left:1rem !important}.my-md-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-md-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 50rem){.m-md-5{margin:1.5rem !important}.mt-md-5{margin-top:1.5rem !important}.mr-md-5{margin-right:1.5rem !important}.mb-md-5{margin-bottom:1.5rem !important}.ml-md-5{margin-left:1.5rem !important}.mx-md-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-md-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-md-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 50rem){.m-md-6{margin:2rem !important}.mt-md-6{margin-top:2rem !important}.mr-md-6{margin-right:2rem !important}.mb-md-6{margin-bottom:2rem !important}.ml-md-6{margin-left:2rem !important}.mx-md-6{margin-right:2rem !important;margin-left:2rem !important}.my-md-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-md-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 50rem){.m-md-7{margin:2.5rem !important}.mt-md-7{margin-top:2.5rem !important}.mr-md-7{margin-right:2.5rem !important}.mb-md-7{margin-bottom:2.5rem !important}.ml-md-7{margin-left:2.5rem !important}.mx-md-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-md-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-md-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 50rem){.m-md-8{margin:3rem !important}.mt-md-8{margin-top:3rem !important}.mr-md-8{margin-right:3rem !important}.mb-md-8{margin-bottom:3rem !important}.ml-md-8{margin-left:3rem !important}.mx-md-8{margin-right:3rem !important;margin-left:3rem !important}.my-md-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-md-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 50rem){.m-md-9{margin:3.5rem !important}.mt-md-9{margin-top:3.5rem !important}.mr-md-9{margin-right:3.5rem !important}.mb-md-9{margin-bottom:3.5rem !important}.ml-md-9{margin-left:3.5rem !important}.mx-md-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-md-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-md-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 50rem){.m-md-10{margin:4rem !important}.mt-md-10{margin-top:4rem !important}.mr-md-10{margin-right:4rem !important}.mb-md-10{margin-bottom:4rem !important}.ml-md-10{margin-left:4rem !important}.mx-md-10{margin-right:4rem !important;margin-left:4rem !important}.my-md-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-md-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 66.5rem){.m-lg-0{margin:0 !important}.mt-lg-0{margin-top:0 !important}.mr-lg-0{margin-right:0 !important}.mb-lg-0{margin-bottom:0 !important}.ml-lg-0{margin-left:0 !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-lg-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 66.5rem){.m-lg-1{margin:.25rem !important}.mt-lg-1{margin-top:.25rem !important}.mr-lg-1{margin-right:.25rem !important}.mb-lg-1{margin-bottom:.25rem !important}.ml-lg-1{margin-left:.25rem !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-lg-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 66.5rem){.m-lg-2{margin:.5rem !important}.mt-lg-2{margin-top:.5rem !important}.mr-lg-2{margin-right:.5rem !important}.mb-lg-2{margin-bottom:.5rem !important}.ml-lg-2{margin-left:.5rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-lg-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 66.5rem){.m-lg-3{margin:.75rem !important}.mt-lg-3{margin-top:.75rem !important}.mr-lg-3{margin-right:.75rem !important}.mb-lg-3{margin-bottom:.75rem !important}.ml-lg-3{margin-left:.75rem !important}.mx-lg-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-lg-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-lg-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 66.5rem){.m-lg-4{margin:1rem !important}.mt-lg-4{margin-top:1rem !important}.mr-lg-4{margin-right:1rem !important}.mb-lg-4{margin-bottom:1rem !important}.ml-lg-4{margin-left:1rem !important}.mx-lg-4{margin-right:1rem !important;margin-left:1rem !important}.my-lg-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-lg-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 66.5rem){.m-lg-5{margin:1.5rem !important}.mt-lg-5{margin-top:1.5rem !important}.mr-lg-5{margin-right:1.5rem !important}.mb-lg-5{margin-bottom:1.5rem !important}.ml-lg-5{margin-left:1.5rem !important}.mx-lg-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-lg-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-lg-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 66.5rem){.m-lg-6{margin:2rem !important}.mt-lg-6{margin-top:2rem !important}.mr-lg-6{margin-right:2rem !important}.mb-lg-6{margin-bottom:2rem !important}.ml-lg-6{margin-left:2rem !important}.mx-lg-6{margin-right:2rem !important;margin-left:2rem !important}.my-lg-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-lg-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 66.5rem){.m-lg-7{margin:2.5rem !important}.mt-lg-7{margin-top:2.5rem !important}.mr-lg-7{margin-right:2.5rem !important}.mb-lg-7{margin-bottom:2.5rem !important}.ml-lg-7{margin-left:2.5rem !important}.mx-lg-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-lg-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-lg-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 66.5rem){.m-lg-8{margin:3rem !important}.mt-lg-8{margin-top:3rem !important}.mr-lg-8{margin-right:3rem !important}.mb-lg-8{margin-bottom:3rem !important}.ml-lg-8{margin-left:3rem !important}.mx-lg-8{margin-right:3rem !important;margin-left:3rem !important}.my-lg-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-lg-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 66.5rem){.m-lg-9{margin:3.5rem !important}.mt-lg-9{margin-top:3.5rem !important}.mr-lg-9{margin-right:3.5rem !important}.mb-lg-9{margin-bottom:3.5rem !important}.ml-lg-9{margin-left:3.5rem !important}.mx-lg-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-lg-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-lg-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 66.5rem){.m-lg-10{margin:4rem !important}.mt-lg-10{margin-top:4rem !important}.mr-lg-10{margin-right:4rem !important}.mb-lg-10{margin-bottom:4rem !important}.ml-lg-10{margin-left:4rem !important}.mx-lg-10{margin-right:4rem !important;margin-left:4rem !important}.my-lg-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-lg-10{margin-right:-4rem !important;margin-left:-4rem !important}}@media (min-width: 87.5rem){.m-xl-0{margin:0 !important}.mt-xl-0{margin-top:0 !important}.mr-xl-0{margin-right:0 !important}.mb-xl-0{margin-bottom:0 !important}.ml-xl-0{margin-left:0 !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.mxn-xl-0{margin-right:-0 !important;margin-left:-0 !important}}@media (min-width: 87.5rem){.m-xl-1{margin:.25rem !important}.mt-xl-1{margin-top:.25rem !important}.mr-xl-1{margin-right:.25rem !important}.mb-xl-1{margin-bottom:.25rem !important}.ml-xl-1{margin-left:.25rem !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.mxn-xl-1{margin-right:-.25rem !important;margin-left:-.25rem !important}}@media (min-width: 87.5rem){.m-xl-2{margin:.5rem !important}.mt-xl-2{margin-top:.5rem !important}.mr-xl-2{margin-right:.5rem !important}.mb-xl-2{margin-bottom:.5rem !important}.ml-xl-2{margin-left:.5rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.mxn-xl-2{margin-right:-.5rem !important;margin-left:-.5rem !important}}@media (min-width: 87.5rem){.m-xl-3{margin:.75rem !important}.mt-xl-3{margin-top:.75rem !important}.mr-xl-3{margin-right:.75rem !important}.mb-xl-3{margin-bottom:.75rem !important}.ml-xl-3{margin-left:.75rem !important}.mx-xl-3{margin-right:.75rem !important;margin-left:.75rem !important}.my-xl-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.mxn-xl-3{margin-right:-.75rem !important;margin-left:-.75rem !important}}@media (min-width: 87.5rem){.m-xl-4{margin:1rem !important}.mt-xl-4{margin-top:1rem !important}.mr-xl-4{margin-right:1rem !important}.mb-xl-4{margin-bottom:1rem !important}.ml-xl-4{margin-left:1rem !important}.mx-xl-4{margin-right:1rem !important;margin-left:1rem !important}.my-xl-4{margin-top:1rem !important;margin-bottom:1rem !important}.mxn-xl-4{margin-right:-1rem !important;margin-left:-1rem !important}}@media (min-width: 87.5rem){.m-xl-5{margin:1.5rem !important}.mt-xl-5{margin-top:1.5rem !important}.mr-xl-5{margin-right:1.5rem !important}.mb-xl-5{margin-bottom:1.5rem !important}.ml-xl-5{margin-left:1.5rem !important}.mx-xl-5{margin-right:1.5rem !important;margin-left:1.5rem !important}.my-xl-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.mxn-xl-5{margin-right:-1.5rem !important;margin-left:-1.5rem !important}}@media (min-width: 87.5rem){.m-xl-6{margin:2rem !important}.mt-xl-6{margin-top:2rem !important}.mr-xl-6{margin-right:2rem !important}.mb-xl-6{margin-bottom:2rem !important}.ml-xl-6{margin-left:2rem !important}.mx-xl-6{margin-right:2rem !important;margin-left:2rem !important}.my-xl-6{margin-top:2rem !important;margin-bottom:2rem !important}.mxn-xl-6{margin-right:-2rem !important;margin-left:-2rem !important}}@media (min-width: 87.5rem){.m-xl-7{margin:2.5rem !important}.mt-xl-7{margin-top:2.5rem !important}.mr-xl-7{margin-right:2.5rem !important}.mb-xl-7{margin-bottom:2.5rem !important}.ml-xl-7{margin-left:2.5rem !important}.mx-xl-7{margin-right:2.5rem !important;margin-left:2.5rem !important}.my-xl-7{margin-top:2.5rem !important;margin-bottom:2.5rem !important}.mxn-xl-7{margin-right:-2.5rem !important;margin-left:-2.5rem !important}}@media (min-width: 87.5rem){.m-xl-8{margin:3rem !important}.mt-xl-8{margin-top:3rem !important}.mr-xl-8{margin-right:3rem !important}.mb-xl-8{margin-bottom:3rem !important}.ml-xl-8{margin-left:3rem !important}.mx-xl-8{margin-right:3rem !important;margin-left:3rem !important}.my-xl-8{margin-top:3rem !important;margin-bottom:3rem !important}.mxn-xl-8{margin-right:-3rem !important;margin-left:-3rem !important}}@media (min-width: 87.5rem){.m-xl-9{margin:3.5rem !important}.mt-xl-9{margin-top:3.5rem !important}.mr-xl-9{margin-right:3.5rem !important}.mb-xl-9{margin-bottom:3.5rem !important}.ml-xl-9{margin-left:3.5rem !important}.mx-xl-9{margin-right:3.5rem !important;margin-left:3.5rem !important}.my-xl-9{margin-top:3.5rem !important;margin-bottom:3.5rem !important}.mxn-xl-9{margin-right:-3.5rem !important;margin-left:-3.5rem !important}}@media (min-width: 87.5rem){.m-xl-10{margin:4rem !important}.mt-xl-10{margin-top:4rem !important}.mr-xl-10{margin-right:4rem !important}.mb-xl-10{margin-bottom:4rem !important}.ml-xl-10{margin-left:4rem !important}.mx-xl-10{margin-right:4rem !important;margin-left:4rem !important}.my-xl-10{margin-top:4rem !important;margin-bottom:4rem !important}.mxn-xl-10{margin-right:-4rem !important;margin-left:-4rem !important}}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-right:0 !important;padding-left:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-right:1rem !important;padding-left:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:2rem !important}.pt-6{padding-top:2rem !important}.pr-6{padding-right:2rem !important}.pb-6{padding-bottom:2rem !important}.pl-6{padding-left:2rem !important}.px-6{padding-right:2rem !important;padding-left:2rem !important}.py-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-7{padding:2.5rem !important}.pt-7{padding-top:2.5rem !important}.pr-7{padding-right:2.5rem !important}.pb-7{padding-bottom:2.5rem !important}.pl-7{padding-left:2.5rem !important}.px-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-8{padding:3rem !important}.pt-8{padding-top:3rem !important}.pr-8{padding-right:3rem !important}.pb-8{padding-bottom:3rem !important}.pl-8{padding-left:3rem !important}.px-8{padding-right:3rem !important;padding-left:3rem !important}.py-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-9{padding:3.5rem !important}.pt-9{padding-top:3.5rem !important}.pr-9{padding-right:3.5rem !important}.pb-9{padding-bottom:3.5rem !important}.pl-9{padding-left:3.5rem !important}.px-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-10{padding:4rem !important}.pt-10{padding-top:4rem !important}.pr-10{padding-right:4rem !important}.pb-10{padding-bottom:4rem !important}.pl-10{padding-left:4rem !important}.px-10{padding-right:4rem !important;padding-left:4rem !important}.py-10{padding-top:4rem !important;padding-bottom:4rem !important}@media (min-width: 20rem){.p-xs-0{padding:0 !important}.pt-xs-0{padding-top:0 !important}.pr-xs-0{padding-right:0 !important}.pb-xs-0{padding-bottom:0 !important}.pl-xs-0{padding-left:0 !important}.px-xs-0{padding-right:0 !important;padding-left:0 !important}.py-xs-0{padding-top:0 !important;padding-bottom:0 !important}.p-xs-1{padding:.25rem !important}.pt-xs-1{padding-top:.25rem !important}.pr-xs-1{padding-right:.25rem !important}.pb-xs-1{padding-bottom:.25rem !important}.pl-xs-1{padding-left:.25rem !important}.px-xs-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xs-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xs-2{padding:.5rem !important}.pt-xs-2{padding-top:.5rem !important}.pr-xs-2{padding-right:.5rem !important}.pb-xs-2{padding-bottom:.5rem !important}.pl-xs-2{padding-left:.5rem !important}.px-xs-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xs-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xs-3{padding:.75rem !important}.pt-xs-3{padding-top:.75rem !important}.pr-xs-3{padding-right:.75rem !important}.pb-xs-3{padding-bottom:.75rem !important}.pl-xs-3{padding-left:.75rem !important}.px-xs-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xs-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xs-4{padding:1rem !important}.pt-xs-4{padding-top:1rem !important}.pr-xs-4{padding-right:1rem !important}.pb-xs-4{padding-bottom:1rem !important}.pl-xs-4{padding-left:1rem !important}.px-xs-4{padding-right:1rem !important;padding-left:1rem !important}.py-xs-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xs-5{padding:1.5rem !important}.pt-xs-5{padding-top:1.5rem !important}.pr-xs-5{padding-right:1.5rem !important}.pb-xs-5{padding-bottom:1.5rem !important}.pl-xs-5{padding-left:1.5rem !important}.px-xs-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xs-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xs-6{padding:2rem !important}.pt-xs-6{padding-top:2rem !important}.pr-xs-6{padding-right:2rem !important}.pb-xs-6{padding-bottom:2rem !important}.pl-xs-6{padding-left:2rem !important}.px-xs-6{padding-right:2rem !important;padding-left:2rem !important}.py-xs-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xs-7{padding:2.5rem !important}.pt-xs-7{padding-top:2.5rem !important}.pr-xs-7{padding-right:2.5rem !important}.pb-xs-7{padding-bottom:2.5rem !important}.pl-xs-7{padding-left:2.5rem !important}.px-xs-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xs-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xs-8{padding:3rem !important}.pt-xs-8{padding-top:3rem !important}.pr-xs-8{padding-right:3rem !important}.pb-xs-8{padding-bottom:3rem !important}.pl-xs-8{padding-left:3rem !important}.px-xs-8{padding-right:3rem !important;padding-left:3rem !important}.py-xs-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xs-9{padding:3.5rem !important}.pt-xs-9{padding-top:3.5rem !important}.pr-xs-9{padding-right:3.5rem !important}.pb-xs-9{padding-bottom:3.5rem !important}.pl-xs-9{padding-left:3.5rem !important}.px-xs-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xs-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xs-10{padding:4rem !important}.pt-xs-10{padding-top:4rem !important}.pr-xs-10{padding-right:4rem !important}.pb-xs-10{padding-bottom:4rem !important}.pl-xs-10{padding-left:4rem !important}.px-xs-10{padding-right:4rem !important;padding-left:4rem !important}.py-xs-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 31.25rem){.p-sm-0{padding:0 !important}.pt-sm-0{padding-top:0 !important}.pr-sm-0{padding-right:0 !important}.pb-sm-0{padding-bottom:0 !important}.pl-sm-0{padding-left:0 !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.p-sm-1{padding:.25rem !important}.pt-sm-1{padding-top:.25rem !important}.pr-sm-1{padding-right:.25rem !important}.pb-sm-1{padding-bottom:.25rem !important}.pl-sm-1{padding-left:.25rem !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-sm-2{padding:.5rem !important}.pt-sm-2{padding-top:.5rem !important}.pr-sm-2{padding-right:.5rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pl-sm-2{padding-left:.5rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-sm-3{padding:.75rem !important}.pt-sm-3{padding-top:.75rem !important}.pr-sm-3{padding-right:.75rem !important}.pb-sm-3{padding-bottom:.75rem !important}.pl-sm-3{padding-left:.75rem !important}.px-sm-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-sm-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-sm-4{padding:1rem !important}.pt-sm-4{padding-top:1rem !important}.pr-sm-4{padding-right:1rem !important}.pb-sm-4{padding-bottom:1rem !important}.pl-sm-4{padding-left:1rem !important}.px-sm-4{padding-right:1rem !important;padding-left:1rem !important}.py-sm-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-sm-5{padding:1.5rem !important}.pt-sm-5{padding-top:1.5rem !important}.pr-sm-5{padding-right:1.5rem !important}.pb-sm-5{padding-bottom:1.5rem !important}.pl-sm-5{padding-left:1.5rem !important}.px-sm-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-sm-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-sm-6{padding:2rem !important}.pt-sm-6{padding-top:2rem !important}.pr-sm-6{padding-right:2rem !important}.pb-sm-6{padding-bottom:2rem !important}.pl-sm-6{padding-left:2rem !important}.px-sm-6{padding-right:2rem !important;padding-left:2rem !important}.py-sm-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-sm-7{padding:2.5rem !important}.pt-sm-7{padding-top:2.5rem !important}.pr-sm-7{padding-right:2.5rem !important}.pb-sm-7{padding-bottom:2.5rem !important}.pl-sm-7{padding-left:2.5rem !important}.px-sm-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-sm-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-sm-8{padding:3rem !important}.pt-sm-8{padding-top:3rem !important}.pr-sm-8{padding-right:3rem !important}.pb-sm-8{padding-bottom:3rem !important}.pl-sm-8{padding-left:3rem !important}.px-sm-8{padding-right:3rem !important;padding-left:3rem !important}.py-sm-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-sm-9{padding:3.5rem !important}.pt-sm-9{padding-top:3.5rem !important}.pr-sm-9{padding-right:3.5rem !important}.pb-sm-9{padding-bottom:3.5rem !important}.pl-sm-9{padding-left:3.5rem !important}.px-sm-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-sm-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-sm-10{padding:4rem !important}.pt-sm-10{padding-top:4rem !important}.pr-sm-10{padding-right:4rem !important}.pb-sm-10{padding-bottom:4rem !important}.pl-sm-10{padding-left:4rem !important}.px-sm-10{padding-right:4rem !important;padding-left:4rem !important}.py-sm-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 50rem){.p-md-0{padding:0 !important}.pt-md-0{padding-top:0 !important}.pr-md-0{padding-right:0 !important}.pb-md-0{padding-bottom:0 !important}.pl-md-0{padding-left:0 !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.p-md-1{padding:.25rem !important}.pt-md-1{padding-top:.25rem !important}.pr-md-1{padding-right:.25rem !important}.pb-md-1{padding-bottom:.25rem !important}.pl-md-1{padding-left:.25rem !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-md-2{padding:.5rem !important}.pt-md-2{padding-top:.5rem !important}.pr-md-2{padding-right:.5rem !important}.pb-md-2{padding-bottom:.5rem !important}.pl-md-2{padding-left:.5rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-md-3{padding:.75rem !important}.pt-md-3{padding-top:.75rem !important}.pr-md-3{padding-right:.75rem !important}.pb-md-3{padding-bottom:.75rem !important}.pl-md-3{padding-left:.75rem !important}.px-md-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-md-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-md-4{padding:1rem !important}.pt-md-4{padding-top:1rem !important}.pr-md-4{padding-right:1rem !important}.pb-md-4{padding-bottom:1rem !important}.pl-md-4{padding-left:1rem !important}.px-md-4{padding-right:1rem !important;padding-left:1rem !important}.py-md-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-md-5{padding:1.5rem !important}.pt-md-5{padding-top:1.5rem !important}.pr-md-5{padding-right:1.5rem !important}.pb-md-5{padding-bottom:1.5rem !important}.pl-md-5{padding-left:1.5rem !important}.px-md-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-md-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-md-6{padding:2rem !important}.pt-md-6{padding-top:2rem !important}.pr-md-6{padding-right:2rem !important}.pb-md-6{padding-bottom:2rem !important}.pl-md-6{padding-left:2rem !important}.px-md-6{padding-right:2rem !important;padding-left:2rem !important}.py-md-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-md-7{padding:2.5rem !important}.pt-md-7{padding-top:2.5rem !important}.pr-md-7{padding-right:2.5rem !important}.pb-md-7{padding-bottom:2.5rem !important}.pl-md-7{padding-left:2.5rem !important}.px-md-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-md-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-md-8{padding:3rem !important}.pt-md-8{padding-top:3rem !important}.pr-md-8{padding-right:3rem !important}.pb-md-8{padding-bottom:3rem !important}.pl-md-8{padding-left:3rem !important}.px-md-8{padding-right:3rem !important;padding-left:3rem !important}.py-md-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-md-9{padding:3.5rem !important}.pt-md-9{padding-top:3.5rem !important}.pr-md-9{padding-right:3.5rem !important}.pb-md-9{padding-bottom:3.5rem !important}.pl-md-9{padding-left:3.5rem !important}.px-md-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-md-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-md-10{padding:4rem !important}.pt-md-10{padding-top:4rem !important}.pr-md-10{padding-right:4rem !important}.pb-md-10{padding-bottom:4rem !important}.pl-md-10{padding-left:4rem !important}.px-md-10{padding-right:4rem !important;padding-left:4rem !important}.py-md-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 66.5rem){.p-lg-0{padding:0 !important}.pt-lg-0{padding-top:0 !important}.pr-lg-0{padding-right:0 !important}.pb-lg-0{padding-bottom:0 !important}.pl-lg-0{padding-left:0 !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.p-lg-1{padding:.25rem !important}.pt-lg-1{padding-top:.25rem !important}.pr-lg-1{padding-right:.25rem !important}.pb-lg-1{padding-bottom:.25rem !important}.pl-lg-1{padding-left:.25rem !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-lg-2{padding:.5rem !important}.pt-lg-2{padding-top:.5rem !important}.pr-lg-2{padding-right:.5rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pl-lg-2{padding-left:.5rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-lg-3{padding:.75rem !important}.pt-lg-3{padding-top:.75rem !important}.pr-lg-3{padding-right:.75rem !important}.pb-lg-3{padding-bottom:.75rem !important}.pl-lg-3{padding-left:.75rem !important}.px-lg-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-lg-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-lg-4{padding:1rem !important}.pt-lg-4{padding-top:1rem !important}.pr-lg-4{padding-right:1rem !important}.pb-lg-4{padding-bottom:1rem !important}.pl-lg-4{padding-left:1rem !important}.px-lg-4{padding-right:1rem !important;padding-left:1rem !important}.py-lg-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-lg-5{padding:1.5rem !important}.pt-lg-5{padding-top:1.5rem !important}.pr-lg-5{padding-right:1.5rem !important}.pb-lg-5{padding-bottom:1.5rem !important}.pl-lg-5{padding-left:1.5rem !important}.px-lg-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-lg-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-lg-6{padding:2rem !important}.pt-lg-6{padding-top:2rem !important}.pr-lg-6{padding-right:2rem !important}.pb-lg-6{padding-bottom:2rem !important}.pl-lg-6{padding-left:2rem !important}.px-lg-6{padding-right:2rem !important;padding-left:2rem !important}.py-lg-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-lg-7{padding:2.5rem !important}.pt-lg-7{padding-top:2.5rem !important}.pr-lg-7{padding-right:2.5rem !important}.pb-lg-7{padding-bottom:2.5rem !important}.pl-lg-7{padding-left:2.5rem !important}.px-lg-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-lg-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-lg-8{padding:3rem !important}.pt-lg-8{padding-top:3rem !important}.pr-lg-8{padding-right:3rem !important}.pb-lg-8{padding-bottom:3rem !important}.pl-lg-8{padding-left:3rem !important}.px-lg-8{padding-right:3rem !important;padding-left:3rem !important}.py-lg-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-lg-9{padding:3.5rem !important}.pt-lg-9{padding-top:3.5rem !important}.pr-lg-9{padding-right:3.5rem !important}.pb-lg-9{padding-bottom:3.5rem !important}.pl-lg-9{padding-left:3.5rem !important}.px-lg-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-lg-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-lg-10{padding:4rem !important}.pt-lg-10{padding-top:4rem !important}.pr-lg-10{padding-right:4rem !important}.pb-lg-10{padding-bottom:4rem !important}.pl-lg-10{padding-left:4rem !important}.px-lg-10{padding-right:4rem !important;padding-left:4rem !important}.py-lg-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media (min-width: 87.5rem){.p-xl-0{padding:0 !important}.pt-xl-0{padding-top:0 !important}.pr-xl-0{padding-right:0 !important}.pb-xl-0{padding-bottom:0 !important}.pl-xl-0{padding-left:0 !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.p-xl-1{padding:.25rem !important}.pt-xl-1{padding-top:.25rem !important}.pr-xl-1{padding-right:.25rem !important}.pb-xl-1{padding-bottom:.25rem !important}.pl-xl-1{padding-left:.25rem !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-xl-2{padding:.5rem !important}.pt-xl-2{padding-top:.5rem !important}.pr-xl-2{padding-right:.5rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pl-xl-2{padding-left:.5rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-xl-3{padding:.75rem !important}.pt-xl-3{padding-top:.75rem !important}.pr-xl-3{padding-right:.75rem !important}.pb-xl-3{padding-bottom:.75rem !important}.pl-xl-3{padding-left:.75rem !important}.px-xl-3{padding-right:.75rem !important;padding-left:.75rem !important}.py-xl-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-xl-4{padding:1rem !important}.pt-xl-4{padding-top:1rem !important}.pr-xl-4{padding-right:1rem !important}.pb-xl-4{padding-bottom:1rem !important}.pl-xl-4{padding-left:1rem !important}.px-xl-4{padding-right:1rem !important;padding-left:1rem !important}.py-xl-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-xl-5{padding:1.5rem !important}.pt-xl-5{padding-top:1.5rem !important}.pr-xl-5{padding-right:1.5rem !important}.pb-xl-5{padding-bottom:1.5rem !important}.pl-xl-5{padding-left:1.5rem !important}.px-xl-5{padding-right:1.5rem !important;padding-left:1.5rem !important}.py-xl-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-xl-6{padding:2rem !important}.pt-xl-6{padding-top:2rem !important}.pr-xl-6{padding-right:2rem !important}.pb-xl-6{padding-bottom:2rem !important}.pl-xl-6{padding-left:2rem !important}.px-xl-6{padding-right:2rem !important;padding-left:2rem !important}.py-xl-6{padding-top:2rem !important;padding-bottom:2rem !important}.p-xl-7{padding:2.5rem !important}.pt-xl-7{padding-top:2.5rem !important}.pr-xl-7{padding-right:2.5rem !important}.pb-xl-7{padding-bottom:2.5rem !important}.pl-xl-7{padding-left:2.5rem !important}.px-xl-7{padding-right:2.5rem !important;padding-left:2.5rem !important}.py-xl-7{padding-top:2.5rem !important;padding-bottom:2.5rem !important}.p-xl-8{padding:3rem !important}.pt-xl-8{padding-top:3rem !important}.pr-xl-8{padding-right:3rem !important}.pb-xl-8{padding-bottom:3rem !important}.pl-xl-8{padding-left:3rem !important}.px-xl-8{padding-right:3rem !important;padding-left:3rem !important}.py-xl-8{padding-top:3rem !important;padding-bottom:3rem !important}.p-xl-9{padding:3.5rem !important}.pt-xl-9{padding-top:3.5rem !important}.pr-xl-9{padding-right:3.5rem !important}.pb-xl-9{padding-bottom:3.5rem !important}.pl-xl-9{padding-left:3.5rem !important}.px-xl-9{padding-right:3.5rem !important;padding-left:3.5rem !important}.py-xl-9{padding-top:3.5rem !important;padding-bottom:3.5rem !important}.p-xl-10{padding:4rem !important}.pt-xl-10{padding-top:4rem !important}.pr-xl-10{padding-right:4rem !important}.pb-xl-10{padding-bottom:4rem !important}.pl-xl-10{padding-left:4rem !important}.px-xl-10{padding-right:4rem !important;padding-left:4rem !important}.py-xl-10{padding-top:4rem !important;padding-bottom:4rem !important}}@media print{.site-footer,.site-button,#edit-this-page,#back-to-top,.site-nav,.main-header{display:none !important}.side-bar{width:100%;height:auto;border-right:0 !important}.site-header{border-bottom:1px solid #eeebee}.site-title{font-size:16px !important;font-weight:700 !important}.text-small{font-size:8pt !important}pre.highlight{border:1px solid #eeebee}.main{max-width:none;margin-left:0}}a.skip-to-main{left:-999px;position:absolute;top:auto;width:1px;height:1px;overflow:hidden;z-index:-999}a.skip-to-main:focus,a.skip-to-main:active{color:#7253ed;background-color:#fff;left:auto;top:auto;width:30%;height:auto;overflow:auto;margin:10px 35%;padding:5px;border-radius:15px;border:4px solid #5e41d0;text-align:center;font-size:1.2em;z-index:999}div.opaque{background-color:#fff} diff --git a/assets/images/just-the-docs.png b/assets/images/just-the-docs.png new file mode 100644 index 0000000000000000000000000000000000000000..81c33065f2794814cbe1a53791d8bc4bfbb91cb1 GIT binary patch literal 20992 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 z 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 literal 0 HcmV?d00001 diff --git a/assets/images/large-image.jpg b/assets/images/large-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c007781c27b4dbdf75b2f48e651be2442a99ba98 GIT binary patch literal 545267 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 J)cmDuEJvL$X|wz) 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�U{IEW4WjdWRr>ACAAcji37LY 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

    w{SkPqN0 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

    a#OUTCzIH6{VGl9-lH5;?)4>Z-+v8i$ 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 ZVRiOpB?U3} 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

    +OstreeAsyncProgress, typedef in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_copy_state, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_finish, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_get, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_get_status, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_get_uint, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_get_uint64, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_get_variant, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_new, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_new_and_connect, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_set, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_set_status, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_set_uint, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_set_uint64, function in Progress notification system for asynchronous operations +
    +
    +
    +ostree_async_progress_set_variant, function in Progress notification system for asynchronous operations +
    +
    +

    B

    +
    +OstreeBootconfigParser, struct in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_clone, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_get, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_get_overlay_initrds, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_new, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_parse, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_parse_at, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_set, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_set_overlay_initrds, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_write, function in ostree-bootconfig-parser +
    +
    +
    +ostree_bootconfig_parser_write_at, function in ostree-bootconfig-parser +
    +
    +
    +ostree_break_hardlink, function in Core repository-independent functions +
    +
    +

    C

    +
    +OstreeChainInputStream, struct in ostree-chain-input-stream +
    +
    +
    +ostree_chain_input_stream_new, function in ostree-chain-input-stream +
    +
    +
    +OstreeChecksumInputStream, struct in ostree-checksum-input-stream +
    +
    +
    +ostree_checksum_b64_from_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_b64_inplace_from_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_b64_inplace_to_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_b64_to_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_bytes_peek, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_bytes_peek_validate, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_file, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_file_async, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_file_async_finish, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_file_at, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_file_from_input, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_from_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_from_bytes_v, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_inplace_from_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_inplace_to_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_input_stream_new, function in ostree-checksum-input-stream +
    +
    +
    +ostree_checksum_to_bytes, function in Core repository-independent functions +
    +
    +
    +ostree_checksum_to_bytes_v, function in Core repository-independent functions +
    +
    +
    +OSTREE_CHECK_VERSION, macro in ostree-version +
    +
    +
    +ostree_check_version, function in Core repository-independent functions +
    +
    +
    +ostree_cmp_checksum_bytes, function in Core repository-independent functions +
    +
    +
    +OstreeCollectionRefv, typedef in ostree-ref +
    +
    +
    +ostree_collection_ref_dup, function in ostree-ref +
    +
    +
    +ostree_collection_ref_dupv, function in ostree-ref +
    +
    +
    +ostree_collection_ref_equal, function in ostree-ref +
    +
    +
    +ostree_collection_ref_free, function in ostree-ref +
    +
    +
    +ostree_collection_ref_freev, function in ostree-ref +
    +
    +
    +ostree_collection_ref_hash, function in ostree-ref +
    +
    +
    +ostree_collection_ref_new, function in ostree-ref +
    +
    +
    +ostree_commit_get_content_checksum, function in Core repository-independent functions +
    +
    +
    +ostree_commit_get_object_sizes, function in Core repository-independent functions +
    +
    +
    +ostree_commit_get_parent, function in Core repository-independent functions +
    +
    +
    +ostree_commit_get_timestamp, function in Core repository-independent functions +
    +
    +
    +OSTREE_COMMIT_GVARIANT_FORMAT, macro in Core repository-independent functions +
    +
    +
    +OSTREE_COMMIT_GVARIANT_STRING, macro in Core repository-independent functions +
    +
    +
    +ostree_commit_metadata_for_bootable, function in Core repository-independent functions +
    +
    +
    +ostree_commit_sizes_entry_copy, function in Core repository-independent functions +
    +
    +
    +ostree_commit_sizes_entry_free, function in Core repository-independent functions +
    +
    +
    +ostree_commit_sizes_entry_new, function in Core repository-independent functions +
    +
    +
    +ostree_content_file_parse, function in Core repository-independent functions +
    +
    +
    +ostree_content_file_parse_at, function in Core repository-independent functions +
    +
    +
    +ostree_content_stream_parse, function in Core repository-independent functions +
    +
    +
    +ostree_content_writer_finish, function in ostree-content-writer +
    +
    +
    +ostree_create_directory_metadata, function in Core repository-independent functions +
    +
    +

    D

    +
    +OstreeDeployment, struct in ostree-deployment +
    +
    +
    +ostree_deployment_clone, function in ostree-deployment +
    +
    +
    +ostree_deployment_equal, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_bootconfig, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_bootcsum, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_bootserial, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_csum, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_deployserial, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_index, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_origin, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_origin_relpath, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_osname, function in ostree-deployment +
    +
    +
    +ostree_deployment_get_unlocked, function in ostree-deployment +
    +
    +
    +ostree_deployment_hash, function in ostree-deployment +
    +
    +
    +ostree_deployment_is_finalization_locked, function in ostree-deployment +
    +
    +
    +ostree_deployment_is_pinned, function in ostree-deployment +
    +
    +
    +ostree_deployment_is_staged, function in ostree-deployment +
    +
    +
    +ostree_deployment_new, function in ostree-deployment +
    +
    +
    +ostree_deployment_origin_remove_transient_state, function in ostree-deployment +
    +
    +
    +ostree_deployment_set_bootconfig, function in ostree-deployment +
    +
    +
    +ostree_deployment_set_bootserial, function in ostree-deployment +
    +
    +
    +ostree_deployment_set_index, function in ostree-deployment +
    +
    +
    +ostree_deployment_set_origin, function in ostree-deployment +
    +
    +
    +ostree_deployment_unlocked_state_to_string, function in ostree-deployment +
    +
    +
    +OstreeDiffFlags, enum in ostree-diff +
    +
    +
    +OstreeDiffItem, struct in ostree-diff +
    +
    +
    +ostree_diff_dirs, function in ostree-diff +
    +
    +
    +ostree_diff_dirs_with_options, function in ostree-diff +
    +
    +
    +ostree_diff_item_ref, function in ostree-diff +
    +
    +
    +ostree_diff_item_unref, function in ostree-diff +
    +
    +
    +ostree_diff_print, function in ostree-diff +
    +
    +
    +OSTREE_DIRMETA_GVARIANT_FORMAT, macro in Core repository-independent functions +
    +
    +
    +OSTREE_DIRMETA_GVARIANT_STRING, macro in Core repository-independent functions +
    +
    +

    F

    +
    +OSTREE_FILEMETA_GVARIANT_FORMAT, macro in Core repository-independent functions +
    +
    +
    +OSTREE_FILEMETA_GVARIANT_STRING, macro in Core repository-independent functions +
    +
    +
    +ostree_fs_get_all_xattrs, function in Core repository-independent functions +
    +
    +
    +ostree_fs_get_all_xattrs_at, function in Core repository-independent functions +
    +
    +

    G

    +
    +OstreeGpgError, enum in GPG signature verification results +
    +
    +
    +OstreeGpgSignatureAttr, enum in GPG signature verification results +
    +
    +
    +OstreeGpgSignatureFormatFlags, enum in GPG signature verification results +
    +
    +
    +OstreeGpgVerifyResult, typedef in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_count_all, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_count_valid, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_describe, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_describe_variant, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_get, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_get_all, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_lookup, function in GPG signature verification results +
    +
    +
    +ostree_gpg_verify_result_require_valid_signature, function in GPG signature verification results +
    +
    +

    H

    +
    +ostree_hash_object_name, function in Core repository-independent functions +
    +
    +

    K

    +
    +OstreeKernelArgs, struct in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_append, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_append_argv, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_append_argv_filtered, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_append_if_missing, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_append_proc_cmdline, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_cleanup, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_contains, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_delete, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_delete_if_present, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_delete_key_entry, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_free, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_from_string, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_get_last_value, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_new, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_new_replace, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_parse_append, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_replace, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_replace_argv, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_replace_take, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_to_string, function in ostree-kernel-args +
    +
    +
    +ostree_kernel_args_to_strv, function in ostree-kernel-args +
    +
    +

    M

    +
    +OSTREE_MAX_METADATA_SIZE, macro in Core repository-independent functions +
    +
    +
    +OSTREE_MAX_METADATA_WARN_SIZE, macro in Core repository-independent functions +
    +
    +
    +ostree_metadata_variant_type, function in Core repository-independent functions +
    +
    +
    +OSTREE_META_KEY_DEPLOY_COLLECTION_ID, macro in ostree-repo-remote-finder +
    +
    +
    +OstreeMutableTree, typedef in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_check_error, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_ensure_dir, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_ensure_parent_dirs, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_fill_empty_from_dirtree, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_get_contents_checksum, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_get_files, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_get_metadata_checksum, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_get_subdirs, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_lookup, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_new, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_new_from_checksum, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_new_from_commit, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_remove, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_replace_file, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_set_contents_checksum, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_set_metadata_checksum, function in In-memory modifiable filesystem tree +
    +
    +
    +ostree_mutable_tree_walk, function in In-memory modifiable filesystem tree +
    +
    +

    O

    +
    +OstreeObjectType, enum in Core repository-independent functions +
    +
    +
    +ostree_object_from_string, function in Core repository-independent functions +
    +
    +
    +ostree_object_name_deserialize, function in Core repository-independent functions +
    +
    +
    +ostree_object_name_serialize, function in Core repository-independent functions +
    +
    +
    +ostree_object_to_string, function in Core repository-independent functions +
    +
    +
    +ostree_object_type_from_string, function in Core repository-independent functions +
    +
    +
    +OSTREE_OBJECT_TYPE_IS_META, macro in Core repository-independent functions +
    +
    +
    +OSTREE_OBJECT_TYPE_LAST, macro in Core repository-independent functions +
    +
    +
    +ostree_object_type_to_string, function in Core repository-independent functions +
    +
    +

    P

    +
    +ostree_parse_refspec, function in Core repository-independent functions +
    +
    +

    R

    +
    +ostree_raw_file_to_archive_z2_stream, function in Core repository-independent functions +
    +
    +
    +ostree_raw_file_to_archive_z2_stream_with_options, function in Core repository-independent functions +
    +
    +
    +ostree_raw_file_to_content_stream, function in Core repository-independent functions +
    +
    +
    +OSTREE_RELEASE_VERSION, macro in ostree-version +
    +
    +
    +OstreeRemote, struct in ostree-remote +
    +
    +
    +ostree_remote_get_name, function in ostree-remote +
    +
    +
    +ostree_remote_get_url, function in ostree-remote +
    +
    +
    +ostree_remote_ref, function in ostree-remote +
    +
    +
    +ostree_remote_unref, function in ostree-remote +
    +
    +
    +OstreeRepo, typedef in OstreeRepo +
    +
    +
    +OstreeRepoAutoLock, typedef in OstreeRepo +
    +
    +
    +OstreeRepoCheckoutMode, enum in OstreeRepo +
    +
    +
    +OstreeRepoCheckoutOverwriteMode, enum in OstreeRepo +
    +
    +
    +OstreeRepoCommitFilter, user_function in OstreeRepo +
    +
    +
    +OstreeRepoCommitFilterResult, enum in OstreeRepo +
    +
    +
    +OstreeRepoCommitIterResult, enum in OstreeRepo +
    +
    +
    +OstreeRepoCommitModifier, typedef in OstreeRepo +
    +
    +
    +OstreeRepoCommitModifierFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoCommitModifierXattrCallback, user_function in OstreeRepo +
    +
    +
    +OstreeRepoCommitState, enum in OstreeRepo +
    +
    +
    +OstreeRepoCommitTraverseFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoFile, typedef in ostree-repo-file +
    +
    +
    +OstreeRepoFinder, struct in ostree-repo-finder +
    +
    +
    +OstreeRepoFinderAvahi, struct in OstreeRepoFinderAvahi +
    +
    +
    +OstreeRepoFinderConfig, struct in OstreeRepoFinderConfig +
    +
    +
    +OstreeRepoFinderMount, struct in OstreeRepoFinderMount +
    +
    +
    +OstreeRepoFinderOverride, struct in OstreeRepoFinderOverride +
    +
    +
    +OstreeRepoFinderResultv, typedef in ostree-repo-finder +
    +
    +
    +OstreeRepoListObjectsFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoListRefsExtFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoLockType, enum in OstreeRepo +
    +
    +
    +OstreeRepoMode, enum in OstreeRepo +
    +
    +
    +OstreeRepoPruneFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoPullFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoRemoteChange, enum in OstreeRepo +
    +
    +
    +OstreeRepoResolveRevExtFlags, enum in OstreeRepo +
    +
    +
    +OstreeRepoTransactionStats, struct in OstreeRepo +
    +
    +
    +ostree_repo_abort_transaction, function in OstreeRepo +
    +
    +
    +ostree_repo_add_gpg_signature_summary, function in OstreeRepo +
    +
    +
    +ostree_repo_append_gpg_signature, function in OstreeRepo +
    +
    +
    +ostree_repo_auto_lock_cleanup, function in OstreeRepo +
    +
    +
    +ostree_repo_auto_lock_push, function in OstreeRepo +
    +
    +
    +ostree_repo_checkout_at, function in OstreeRepo +
    +
    +
    +ostree_repo_checkout_at_options_set_devino, function in OstreeRepo +
    +
    +
    +ostree_repo_checkout_gc, function in OstreeRepo +
    +
    +
    +ostree_repo_checkout_tree, function in OstreeRepo +
    +
    +
    +ostree_repo_checkout_tree_at, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_add_composefs_metadata, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_new, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_ref, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_set_devino_cache, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_set_sepolicy, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_set_sepolicy_from_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_set_xattr_callback, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_modifier_unref, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_transaction, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_cleanup, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_clear, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_get_dir, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_get_file, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_init_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_init_dirtree, function in OstreeRepo +
    +
    +
    +ostree_repo_commit_traverse_iter_next, function in OstreeRepo +
    +
    +
    +ostree_repo_copy_config, function in OstreeRepo +
    +
    +
    +ostree_repo_create, function in OstreeRepo +
    +
    +
    +ostree_repo_create_at, function in OstreeRepo +
    +
    +
    +ostree_repo_delete_object, function in OstreeRepo +
    +
    +
    +ostree_repo_devino_cache_get_type, function in OstreeRepo +
    +
    +
    +ostree_repo_devino_cache_new, function in OstreeRepo +
    +
    +
    +ostree_repo_devino_cache_ref, function in OstreeRepo +
    +
    +
    +ostree_repo_devino_cache_unref, function in OstreeRepo +
    +
    +
    +ostree_repo_equal, function in OstreeRepo +
    +
    +
    +ostree_repo_export_tree_to_archive, function in OstreeRepo +
    +
    +
    +ostree_repo_file_ensure_resolved, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_get_checksum, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_get_repo, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_get_root, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_get_xattrs, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_find_child, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_get_contents, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_get_contents_checksum, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_get_metadata, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_get_metadata_checksum, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_query_child, function in ostree-repo-file +
    +
    +
    +ostree_repo_file_tree_set_metadata, function in ostree-repo-file +
    +
    +
    +ostree_repo_finder_avahi_new, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_avahi_start, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_avahi_stop, function in OstreeRepoFinderAvahi +
    +
    +
    +ostree_repo_finder_config_new, function in OstreeRepoFinderConfig +
    +
    +
    +ostree_repo_finder_mount_new, function in OstreeRepoFinderMount +
    +
    +
    +ostree_repo_finder_override_add_uri, function in OstreeRepoFinderOverride +
    +
    +
    +ostree_repo_finder_override_new, function in OstreeRepoFinderOverride +
    +
    +
    +ostree_repo_finder_resolve_all_async, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_resolve_all_finish, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_resolve_async, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_resolve_finish, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_result_compare, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_result_dup, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_result_free, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_result_freev, function in ostree-repo-finder +
    +
    +
    +ostree_repo_finder_result_new, function in ostree-repo-finder +
    +
    +
    +ostree_repo_find_remotes_async, function in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_find_remotes_finish, function in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_fsck_object, function in OstreeRepo +
    +
    +
    +ostree_repo_get_bootloader, function in OstreeRepo +
    +
    +
    +ostree_repo_get_collection_id, function in OstreeRepo +
    +
    +
    +ostree_repo_get_config, function in OstreeRepo +
    +
    +
    +ostree_repo_get_default_repo_finders, function in OstreeRepo +
    +
    +
    +ostree_repo_get_dfd, function in OstreeRepo +
    +
    +
    +ostree_repo_get_disable_fsync, function in OstreeRepo +
    +
    +
    +ostree_repo_get_min_free_space_bytes, function in OstreeRepo +
    +
    +
    +ostree_repo_get_mode, function in OstreeRepo +
    +
    +
    +ostree_repo_get_parent, function in OstreeRepo +
    +
    +
    +ostree_repo_get_path, function in OstreeRepo +
    +
    +
    +ostree_repo_get_remote_boolean_option, function in OstreeRepo +
    +
    +
    +ostree_repo_get_remote_list_option, function in OstreeRepo +
    +
    +
    +ostree_repo_get_remote_option, function in OstreeRepo +
    +
    +
    +ostree_repo_gpg_sign_data, function in OstreeRepo +
    +
    +
    +ostree_repo_gpg_verify_data, function in OstreeRepo +
    +
    +
    +ostree_repo_hash, function in OstreeRepo +
    +
    +
    +ostree_repo_has_object, function in OstreeRepo +
    +
    +
    +ostree_repo_import_archive_to_mtree, function in OstreeRepo +
    +
    +
    +ostree_repo_import_object_from, function in OstreeRepo +
    +
    +
    +ostree_repo_import_object_from_with_trust, function in OstreeRepo +
    +
    +
    +ostree_repo_is_system, function in OstreeRepo +
    +
    +
    +ostree_repo_is_writable, function in OstreeRepo +
    +
    +
    +ostree_repo_list_collection_refs, function in OstreeRepo +
    +
    +
    +ostree_repo_list_commit_objects_starting_with, function in OstreeRepo +
    +
    +
    +ostree_repo_list_objects, function in OstreeRepo +
    +
    +
    +OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE, macro in OstreeRepo +
    +
    +
    +ostree_repo_list_refs, function in OstreeRepo +
    +
    +
    +ostree_repo_list_refs_ext, function in OstreeRepo +
    +
    +
    +ostree_repo_list_static_delta_indexes, function in OstreeRepo +
    +
    +
    +ostree_repo_list_static_delta_names, function in OstreeRepo +
    +
    +
    +ostree_repo_load_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_load_file, function in OstreeRepo +
    +
    +
    +ostree_repo_load_object_stream, function in OstreeRepo +
    +
    +
    +ostree_repo_load_variant, function in OstreeRepo +
    +
    +
    +ostree_repo_load_variant_if_exists, function in OstreeRepo +
    +
    +
    +ostree_repo_lock_pop, function in OstreeRepo +
    +
    +
    +ostree_repo_lock_push, function in OstreeRepo +
    +
    +
    +ostree_repo_mark_commit_partial, function in OstreeRepo +
    +
    +
    +ostree_repo_mark_commit_partial_reason, function in OstreeRepo +
    +
    +
    +OSTREE_REPO_METADATA_REF, macro in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_mode_from_string, function in OstreeRepo +
    +
    +
    +ostree_repo_new, function in OstreeRepo +
    +
    +
    +ostree_repo_new_default, function in OstreeRepo +
    +
    +
    +ostree_repo_new_for_sysroot_path, function in OstreeRepo +
    +
    +
    +ostree_repo_open, function in OstreeRepo +
    +
    +
    +ostree_repo_open_at, function in OstreeRepo +
    +
    +
    +ostree_repo_prepare_transaction, function in OstreeRepo +
    +
    +
    +ostree_repo_prune, function in OstreeRepo +
    +
    +
    +ostree_repo_prune_from_reachable, function in OstreeRepo +
    +
    +
    +ostree_repo_prune_static_deltas, function in OstreeRepo +
    +
    +
    +ostree_repo_pull, function in OstreeRepo +
    +
    +
    +ostree_repo_pull_default_console_progress_changed, function in OstreeRepo +
    +
    +
    +ostree_repo_pull_from_remotes_async, function in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_pull_from_remotes_finish, function in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_pull_one_dir, function in OstreeRepo +
    +
    +
    +ostree_repo_pull_with_options, function in OstreeRepo +
    +
    +
    +ostree_repo_query_object_storage_size, function in OstreeRepo +
    +
    +
    +ostree_repo_read_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_read_commit_detached_metadata, function in OstreeRepo +
    +
    +
    +ostree_repo_regenerate_metadata, function in OstreeRepo +
    +
    +
    +ostree_repo_regenerate_summary, function in OstreeRepo +
    +
    +
    +ostree_repo_reload_config, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_add, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_change, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_delete, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_fetch_summary, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_fetch_summary_with_options, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_get_gpg_keys, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_get_gpg_verify, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_get_gpg_verify_summary, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_get_url, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_gpg_import, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_list, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_list_collection_refs, function in OstreeRepo +
    +
    +
    +ostree_repo_remote_list_refs, function in OstreeRepo +
    +
    +
    +ostree_repo_resolve_collection_ref, function in OstreeRepo +
    +
    +
    +ostree_repo_resolve_keyring_for_collection, function in ostree-repo-remote-finder +
    +
    +
    +ostree_repo_resolve_rev, function in OstreeRepo +
    +
    +
    +ostree_repo_resolve_rev_ext, function in OstreeRepo +
    +
    +
    +ostree_repo_scan_hardlinks, function in OstreeRepo +
    +
    +
    +ostree_repo_set_alias_ref_immediate, function in OstreeRepo +
    +
    +
    +ostree_repo_set_cache_dir, function in OstreeRepo +
    +
    +
    +ostree_repo_set_collection_id, function in OstreeRepo +
    +
    +
    +ostree_repo_set_collection_ref_immediate, function in OstreeRepo +
    +
    +
    +ostree_repo_set_disable_fsync, function in OstreeRepo +
    +
    +
    +ostree_repo_set_ref_immediate, function in OstreeRepo +
    +
    +
    +ostree_repo_signature_verify_commit_data, function in OstreeRepo +
    +
    +
    +ostree_repo_sign_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_sign_delta, function in OstreeRepo +
    +
    +
    +ostree_repo_static_delta_execute_offline, function in OstreeRepo +
    +
    +
    +ostree_repo_static_delta_execute_offline_with_signature, function in OstreeRepo +
    +
    +
    +ostree_repo_static_delta_generate, function in OstreeRepo +
    +
    +
    +ostree_repo_static_delta_reindex, function in OstreeRepo +
    +
    +
    +ostree_repo_static_delta_verify_signature, function in OstreeRepo +
    +
    +
    +ostree_repo_transaction_set_collection_ref, function in OstreeRepo +
    +
    +
    +ostree_repo_transaction_set_ref, function in OstreeRepo +
    +
    +
    +ostree_repo_transaction_set_refspec, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_commit_union, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_commit_union_with_parents, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_commit_with_flags, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_new_parents, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_new_reachable, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_parents_get_commits, function in OstreeRepo +
    +
    +
    +ostree_repo_traverse_reachable_refs, function in OstreeRepo +
    +
    +
    +ostree_repo_verify_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_verify_commit_ext, function in OstreeRepo +
    +
    +
    +ostree_repo_verify_commit_for_remote, function in OstreeRepo +
    +
    +
    +ostree_repo_verify_summary, function in OstreeRepo +
    +
    +
    +ostree_repo_write_archive_to_mtree, function in OstreeRepo +
    +
    +
    +ostree_repo_write_archive_to_mtree_from_fd, function in OstreeRepo +
    +
    +
    +ostree_repo_write_commit, function in OstreeRepo +
    +
    +
    +ostree_repo_write_commit_detached_metadata, function in OstreeRepo +
    +
    +
    +ostree_repo_write_commit_with_time, function in OstreeRepo +
    +
    +
    +ostree_repo_write_config, function in OstreeRepo +
    +
    +
    +ostree_repo_write_content, function in OstreeRepo +
    +
    +
    +ostree_repo_write_content_async, function in OstreeRepo +
    +
    +
    +ostree_repo_write_content_finish, function in OstreeRepo +
    +
    +
    +ostree_repo_write_content_trusted, function in OstreeRepo +
    +
    +
    +ostree_repo_write_dfd_to_mtree, function in OstreeRepo +
    +
    +
    +ostree_repo_write_directory_to_mtree, function in OstreeRepo +
    +
    +
    +ostree_repo_write_metadata, function in OstreeRepo +
    +
    +
    +ostree_repo_write_metadata_async, function in OstreeRepo +
    +
    +
    +ostree_repo_write_metadata_finish, function in OstreeRepo +
    +
    +
    +ostree_repo_write_metadata_stream_trusted, function in OstreeRepo +
    +
    +
    +ostree_repo_write_metadata_trusted, function in OstreeRepo +
    +
    +
    +ostree_repo_write_mtree, function in OstreeRepo +
    +
    +
    +ostree_repo_write_regfile, function in OstreeRepo +
    +
    +
    +ostree_repo_write_regfile_inline, function in OstreeRepo +
    +
    +
    +ostree_repo_write_symlink, function in OstreeRepo +
    +
    +

    S

    +
    +OstreeSePolicy, typedef in SELinux policy management +
    +
    +
    +OstreeSePolicyRestoreconFlags, enum in SELinux policy management +
    +
    +
    +ostree_sepolicy_fscreatecon_cleanup, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_get_csum, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_get_label, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_get_name, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_get_path, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_new, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_new_at, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_new_from_commit, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_restorecon, function in SELinux policy management +
    +
    +
    +ostree_sepolicy_setfscreatecon, function in SELinux policy management +
    +
    +
    +OstreeSign, struct in Signature management +
    +
    +
    +ostree_sign_add_pk, function in Signature management +
    +
    +
    +ostree_sign_clear_keys, function in Signature management +
    +
    +
    +ostree_sign_commit, function in Signature management +
    +
    +
    +ostree_sign_commit_verify, function in Signature management +
    +
    +
    +ostree_sign_data, function in Signature management +
    +
    +
    +ostree_sign_data_verify, function in Signature management +
    +
    +
    +ostree_sign_get_all, function in Signature management +
    +
    +
    +ostree_sign_get_by_name, function in Signature management +
    +
    +
    +ostree_sign_get_name, function in Signature management +
    +
    +
    +ostree_sign_load_pk, function in Signature management +
    +
    +
    +ostree_sign_metadata_format, function in Signature management +
    +
    +
    +ostree_sign_metadata_key, function in Signature management +
    +
    +
    +ostree_sign_set_pk, function in Signature management +
    +
    +
    +ostree_sign_set_sk, function in Signature management +
    +
    +
    +ostree_sign_summary, function in Signature management +
    +
    +
    +OstreeStaticDeltaGenerateOpt, enum in OstreeRepo +
    +
    +
    +OSTREE_SUMMARY_GVARIANT_FORMAT, macro in Core repository-independent functions +
    +
    +
    +OSTREE_SUMMARY_GVARIANT_STRING, macro in Core repository-independent functions +
    +
    +
    +OstreeSysroot, typedef in Root partition mount point +
    +
    +
    +OstreeSysrootSimpleWriteDeploymentFlags, enum in Root partition mount point +
    +
    +
    +OstreeSysrootUpgrader, typedef in Simple upgrade class +
    +
    +
    +OstreeSysrootUpgraderFlags, enum in Simple upgrade class +
    +
    +
    +OstreeSysrootUpgraderPullFlags, enum in Simple upgrade class +
    +
    +
    +ostree_sysroot_change_finalization, function in Root partition mount point +
    +
    +
    +ostree_sysroot_cleanup, function in Root partition mount point +
    +
    +
    +ostree_sysroot_cleanup_prune_repo, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deployment_set_kargs, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deployment_set_kargs_in_place, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deployment_set_mutable, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deployment_set_pinned, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deployment_unlock, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deploy_tree, function in Root partition mount point +
    +
    +
    +ostree_sysroot_deploy_tree_with_options, function in Root partition mount point +
    +
    +
    +ostree_sysroot_ensure_initialized, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_booted_deployment, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_bootversion, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_deployments, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_deployment_directory, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_deployment_dirpath, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_deployment_origin_path, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_fd, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_merge_deployment, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_path, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_repo, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_staged_deployment, function in Root partition mount point +
    +
    +
    +ostree_sysroot_get_subbootversion, function in Root partition mount point +
    +
    +
    +ostree_sysroot_initialize, function in Root partition mount point +
    +
    +
    +ostree_sysroot_initialize_with_mount_namespace, function in Root partition mount point +
    +
    +
    +ostree_sysroot_init_osname, function in Root partition mount point +
    +
    +
    +ostree_sysroot_is_booted, function in Root partition mount point +
    +
    +
    +ostree_sysroot_load, function in Root partition mount point +
    +
    +
    +ostree_sysroot_load_if_changed, function in Root partition mount point +
    +
    +
    +ostree_sysroot_lock, function in Root partition mount point +
    +
    +
    +ostree_sysroot_lock_async, function in Root partition mount point +
    +
    +
    +ostree_sysroot_lock_finish, function in Root partition mount point +
    +
    +
    +ostree_sysroot_new, function in Root partition mount point +
    +
    +
    +ostree_sysroot_new_default, function in Root partition mount point +
    +
    +
    +ostree_sysroot_origin_new_from_refspec, function in Root partition mount point +
    +
    +
    +ostree_sysroot_prepare_cleanup, function in Root partition mount point +
    +
    +
    +ostree_sysroot_query_deployments_for, function in Root partition mount point +
    +
    +
    +ostree_sysroot_repo, function in Root partition mount point +
    +
    +
    +ostree_sysroot_require_booted_deployment, function in Root partition mount point +
    +
    +
    +ostree_sysroot_set_mount_namespace_in_use, function in Root partition mount point +
    +
    +
    +ostree_sysroot_simple_write_deployment, function in Root partition mount point +
    +
    +
    +ostree_sysroot_stage_overlay_initrd, function in Root partition mount point +
    +
    +
    +ostree_sysroot_stage_tree, function in Root partition mount point +
    +
    +
    +ostree_sysroot_stage_tree_with_options, function in Root partition mount point +
    +
    +
    +ostree_sysroot_try_lock, function in Root partition mount point +
    +
    +
    +ostree_sysroot_unload, function in Root partition mount point +
    +
    +
    +ostree_sysroot_unlock, function in Root partition mount point +
    +
    +
    +ostree_sysroot_update_post_copy, function in Root partition mount point +
    +
    +
    +ostree_sysroot_upgrader_check_timestamps, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_deploy, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_dup_origin, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_get_origin, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_get_origin_description, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_new, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_new_for_os, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_new_for_os_with_flags, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_pull, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_pull_one_dir, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_upgrader_set_origin, function in Simple upgrade class +
    +
    +
    +ostree_sysroot_write_deployments, function in Root partition mount point +
    +
    +
    +ostree_sysroot_write_deployments_with_options, function in Root partition mount point +
    +
    +
    +ostree_sysroot_write_origin_file, function in Root partition mount point +
    +
    +

    T

    +
    +OSTREE_TREE_GVARIANT_FORMAT, macro in Core repository-independent functions +
    +
    +
    +OSTREE_TREE_GVARIANT_STRING, macro in Core repository-independent functions +
    +
    +

    V

    +
    +ostree_validate_checksum_string, function in Core repository-independent functions +
    +
    +
    +ostree_validate_collection_id, function in Core repository-independent functions +
    +
    +
    +ostree_validate_remote_name, function in Core repository-independent functions +
    +
    +
    +ostree_validate_rev, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_checksum_string, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_commit, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_csum_v, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_dirmeta, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_dirtree, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_file_mode, function in Core repository-independent functions +
    +
    +
    +ostree_validate_structureof_objtype, function in Core repository-independent functions +
    +
    +
    +OSTREE_VERSION, macro in ostree-version +
    +
    +
    +OSTREE_VERSION_HEX, macro in ostree-version +
    +
    +
    +OSTREE_VERSION_S, macro in ostree-version +
    +
    +

    Y

    +
    +OSTREE_YEAR_VERSION, macro in ostree-version +
    +
    + + + + + \ No newline at end of file diff --git a/reference/right-insensitive.png b/reference/right-insensitive.png new file mode 100644 index 0000000000000000000000000000000000000000..4c95785b907b978f36674cd98bf5302669c15c1b GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefG`u!(zUX23=E7+o-U3d7N^fn+URvSL8NuRG*{E) z?#-+97X-^pidQ*u@StO1(S@7g8g>nnA24$?ty?)cmuaa|Y>ez2*_Ia?6HP4j{3LIs zTr!s1ao_Sz^~3e4zRJGAjKZGn=XP#)Wmuo-QN>teTzzI!&R*jMI^Oa#7_ukLYdicf zOx;1mb-rt04s-c|uIH8fnX}$)XJa^0_-F3(pA%=sGI<|(n_*&=yYt96+n5InXn_GN+EraJI9q(O+n{6MQKErp&KxRvpfn0xh z`sSMqH(2Z%?kaFBTf06W^y=UDA9gR9YrwNS*1pjB((0K%&+SbAx3`XA&dKZ}j*nX7 QfdRze>FVdQ&MBb@09|aA9{>OV literal 0 HcmV?d00001 diff --git a/reference/right.png b/reference/right.png new file mode 100644 index 0000000000000000000000000000000000000000..76260ec8865f4e13cd269ec62eccd78a33adba3c GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefRMbR+#PqI2*V^#7sn8b(^oI8=W9$9IsUQVezxzH zy`G{eu0`y#boSlU-NAlQG~=D)BPJG4k(^0qdDa(AdQvI0d|vJT=i7_<_D6`Cy?Dm; zP0@1EeB~D|O$oQe*sxL-P;q{2UCr}fN-o#M~tpZzsGyfNz46SZlIJCbKH zZQscEqpOfBCPDgx dt +{ + padding-top: 0.25em; + padding-bottom: 0.25em; + font-weight: bold; +} + +dl.toc > dl +{ + padding-bottom: 0.5em; +} + +.parameter +{ + font-style: normal; +} + +.footer +{ + padding-top: 3.5em; + /* tango:aluminium 3 */ + color: #babdb6; + text-align: center; + font-size: 80%; +} + +.informalfigure, +.figure +{ + margin: 1em; +} + +.informalexample, +.example +{ + margin-top: 1em; + margin-bottom: 1em; +} + +.warning +{ + /* tango:orange 0/1 */ + background: #ffeed9; + background: rgba(252, 175, 62, 0.1); + border-color: #ffb04f; + border-color: rgba(252, 175, 62, 0.2); +} +.note +{ + /* tango:chameleon 0/0.5 */ + background: #d8ffb2; + background: rgba(138, 226, 52, 0.1); + border-color: #abf562; + border-color: rgba(138, 226, 52, 0.2); +} +div.blockquote +{ + border-color: #eeeeec; +} +.note, .warning, div.blockquote +{ + padding: 0.5em; + border-width: 1px; + border-style: solid; + margin: 2em; +} +.note p, .warning p +{ + margin: 0; +} + +div.warning h3.title, +div.note h3.title +{ + display: none; +} + +p + div.section +{ + margin-top: 1em; +} + +div.refnamediv, +div.refsynopsisdiv, +div.refsect1, +div.refsect2, +div.toc, +div.section +{ + margin-bottom: 1em; +} + +/* blob links */ +h2 .extralinks, h3 .extralinks +{ + float: right; + /* tango:aluminium 3 */ + color: #babdb6; + font-size: 80%; + font-weight: normal; +} + +.lineart +{ + color: #d3d7cf; + font-weight: normal; +} + +.annotation +{ + /* tango:aluminium 5 */ + color: #555753; + font-weight: normal; +} + +.structfield +{ + font-style: normal; + font-weight: normal; +} + +acronym,abbr +{ + border-bottom: 1px dotted gray; +} + +.listing_frame { + /* tango:sky blue 1 */ + border: solid 1px #729fcf; + border: solid 1px rgba(114, 159, 207, 0.2); + padding: 0px; +} + +.listing_lines, .listing_code { + margin-top: 0px; + margin-bottom: 0px; + padding: 0.5em; +} +.listing_lines { + /* tango:sky blue 0.5 */ + background: #a6c5e3; + background: rgba(114, 159, 207, 0.2); + /* tango:aluminium 6 */ + color: #2e3436; +} +.listing_code { + /* tango:sky blue 0 */ + background: #e6f3ff; + background: rgba(114, 159, 207, 0.1); +} +.listing_code .programlisting { + /* override from previous */ + border: none 0px; + padding: 0px; + background: none; +} +.listing_lines pre, .listing_code pre { + margin: 0px; +} + +@media screen { + /* these have a as a first child, but since there are no parent selectors + * we can't use that. */ + a.footnote + { + position: relative; + top: 0em ! important; + } + /* this is needed so that the local anchors are displayed below the naviagtion */ + div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] + { + display: inline-block; + position: relative; + top:-5em; + } + /* this seems to be a bug in the xsl style sheets when generating indexes */ + div.index div.index + { + top: 0em; + } + /* make space for the fixed navigation bar and add space at the bottom so that + * link targets appear somewhat close to top + */ + body + { + padding-top: 2.5em; + padding-bottom: 500px; + max-width: 60em; + } + p + { + max-width: 60em; + } + /* style and size the navigation bar */ + table.navigation#top + { + position: fixed; + background: #e2e2e2; + border-bottom: solid 1px #babdb6; + border-spacing: 5px; + margin-top: 0; + margin-bottom: 0; + top: 0; + left: 0; + z-index: 10; + } + table.navigation#top td + { + padding-left: 6px; + padding-right: 6px; + } + .navigation a, .navigation a:visited + { + /* tango:sky blue 3 */ + color: #204a87; + } + .navigation a:hover + { + /* tango:sky blue 2 */ + color: #3465a4; + } + td.shortcuts + { + /* tango:sky blue 2 */ + color: #3465a4; + font-size: 80%; + white-space: nowrap; + } + td.shortcuts .dim + { + color: #babdb6; + } + .navigation .title + { + font-size: 80%; + max-width: none; + margin: 0px; + font-weight: normal; + } +} +@media screen and (min-width: 60em) { + /* screen larger than 60em */ + body { margin: auto; } +} +@media screen and (max-width: 60em) { + /* screen less than 60em */ + #nav_hierarchy { display: none; } + #nav_interfaces { display: none; } + #nav_prerequisites { display: none; } + #nav_derived_interfaces { display: none; } + #nav_implementations { display: none; } + #nav_child_properties { display: none; } + #nav_style_properties { display: none; } + #nav_index { display: none; } + #nav_glossary { display: none; } + .gallery_image { display: none; } + .property_flags { display: none; } + .signal_flags { display: none; } + .parameter_annotations { display: none; } + .enum_member_annotations { display: none; } + .struct_member_annotations { display: none; } + .union_member_annotations { display: none; } + /* now that a column is hidden, optimize space */ + col.parameters_name { width: auto; } + col.parameters_description { width: auto; } + col.struct_members_name { width: auto; } + col.struct_members_description { width: auto; } + col.enum_members_name { width: auto; } + col.enum_members_description { width: auto; } + col.union_members_name { width: auto; } + col.union_members_description { width: auto; } + .listing_lines { display: none; } +} +@media print { + table.navigation { + visibility: collapse; + display: none; + } + div.titlepage table.navigation { + visibility: visible; + display: table; + background: #e2e2e2; + border: solid 1px #babdb6; + margin-top: 0; + margin-bottom: 0; + top: 0; + left: 0; + height: 3em; + } +} + +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.hll { background-color: #ffffcc } +.c { color: #3D7B7B; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #008000; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.cp { color: #9C6500 } /* Comment.Preproc */ +.cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #E40000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #008400 } /* Generic.Inserted */ +.go { color: #717171 } /* Generic.Output */ +.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0044DD } /* Generic.Traceback */ +.kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #008000 } /* Keyword.Pseudo */ +.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #B00040 } /* Keyword.Type */ +.m { color: #666666 } /* Literal.Number */ +.s { color: #BA2121 } /* Literal.String */ +.na { color: #687822 } /* Name.Attribute */ +.nb { color: #008000 } /* Name.Builtin */ +.nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.no { color: #880000 } /* Name.Constant */ +.nd { color: #AA22FF } /* Name.Decorator */ +.ni { color: #717171; font-weight: bold } /* Name.Entity */ +.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.nf { color: #0000FF } /* Name.Function */ +.nl { color: #767600 } /* Name.Label */ +.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.nt { color: #008000; font-weight: bold } /* Name.Tag */ +.nv { color: #19177C } /* Name.Variable */ +.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mb { color: #666666 } /* Literal.Number.Bin */ +.mf { color: #666666 } /* Literal.Number.Float */ +.mh { color: #666666 } /* Literal.Number.Hex */ +.mi { color: #666666 } /* Literal.Number.Integer */ +.mo { color: #666666 } /* Literal.Number.Oct */ +.sa { color: #BA2121 } /* Literal.String.Affix */ +.sb { color: #BA2121 } /* Literal.String.Backtick */ +.sc { color: #BA2121 } /* Literal.String.Char */ +.dl { color: #BA2121 } /* Literal.String.Delimiter */ +.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #BA2121 } /* Literal.String.Double */ +.se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #BA2121 } /* Literal.String.Heredoc */ +.si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.sx { color: #008000 } /* Literal.String.Other */ +.sr { color: #A45A77 } /* Literal.String.Regex */ +.s1 { color: #BA2121 } /* Literal.String.Single */ +.ss { color: #19177C } /* Literal.String.Symbol */ +.bp { color: #008000 } /* Name.Builtin.Pseudo */ +.fm { color: #0000FF } /* Name.Function.Magic */ +.vc { color: #19177C } /* Name.Variable.Class */ +.vg { color: #19177C } /* Name.Variable.Global */ +.vi { color: #19177C } /* Name.Variable.Instance */ +.vm { color: #19177C } /* Name.Variable.Magic */ +.il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/reference/up-insensitive.png b/reference/up-insensitive.png new file mode 100644 index 0000000000000000000000000000000000000000..f40498606db349a7321cf6b470523e836ee7ac2e GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefG~@Ex#w@70gTL^E{-7zACwHGSRJaopUzr*FR_KPpkxheNzTDP+%{a~ox zRb6~e-_l%s#;V|Jw-)bO$G_X=4F`Y7SBoCzyjAZQ8BPW>ywAP8?pbBsZ|wt?+h6S6&uqY)kkMnwQQEd@7k`4t@sCCO z@7MoiEI4Q_#IB70vhu7Ab+>SXLxu@LWH Qzz|~aboFyt=akR{08E^fv;Y7A literal 0 HcmV?d00001 diff --git a/reference/up.png b/reference/up.png new file mode 100644 index 0000000000000000000000000000000000000000..80b4b37e997d69b2e128bc3090bc447ccb74bbe9 GIT binary patch literal 260 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefRFevZLys@4W>+6GUE!tU04Ii{0w_tkMIDB?rA5 zttYTN + + + + + + + + + + + + + + + + + + + + + + + + +Related Projects | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Related Projects + + +

    + + +
      +
    1. Combining dpkg/rpm + (BTRFS/LVM)
    2. +
    3. ChromiumOS updater
    4. +
    5. Ubuntu Image Based Updates
    6. +
    7. Clear Linux Software update
    8. +
    9. casync
    10. +
    11. Mender.io
    12. +
    13. OLPC update
    14. +
    15. NixOS / Nix
    16. +
    17. Solaris IPS
    18. +
    19. Google servers (custom rsync-like approach, live updates)
    20. +
    21. Conary
    22. +
    23. bmap
    24. +
    25. Git
    26. +
    27. Conda
    28. +
    29. rpm-ostree
    30. +
    31. GNOME Continuous
    32. +
    33. Docker
    34. +
    35. Docker-related: Balena
    36. +
    37. Torizon Platform
        +
      1. Torizon OS
      2. +
      3. TorizonCore Builder
      4. +
      5. Torizon Cloud
      6. +
      +
    38. +
    + + + +

    OSTree is in many ways very evolutionary. It builds on concepts and +ideas introduced from many different projects such as +Systemd Stateless, +Systemd Bootloader Spec, +Chromium Autoupdate, +the much older +Fedora/Red Hat Stateless Project, +Linux VServer +and many more.

    + +

    As mentioned elsewhere, OSTree is strongly influenced by package +manager designs as well. This page is not intended to be an +exhaustive list of such projects, but we will try to keep it up to +date, and relatively agnostic.

    + +

    Broadly speaking, projects in this area fall into two camps; either +a tool to snapshot systems on the client side (dpkg/rpm + BTRFS/LVM), +or a tool to compose on a server and replicate (ChromiumOS, Clear +Linux). OSTree is flexible enough to do both.

    + +

    Note that this section of the documentation is almost entirely +focused on the “ostree for host” model; the flatpak +project uses libostree to store application data, distinct from the +host system management model.

    +

    + + + Combining dpkg/rpm + (BTRFS/LVM) + + +

    + + +

    In this approach, one uses a block/filesystem snapshot tool underneath +the system package manager.

    + +

    The +oVirt Node imgbased +tool is an example of this approach, as are a few others below.

    + +

    Regarding BTRFS +in particular - the OSTree author believes that Linux storage is a +wide world, and while BTRFS is quite good, it is not everywhere now, +nor will it be in the near future. There are other recently developed +filesystems like f2fs, and Red +Hat Enterprise Linux still defaults to +XFS.

    + +

    Using a snapshot tool underneath a package manager does help +significantly. In the rest of this text, we will use “BTRFS” as a +mostly generic tool for filesystem snapshots.

    + +

    The obvious thing to do is layer BTRFS under dpkg/rpm, and have a +separate subvolume for /home so rollbacks don’t lose your data. See +e.g. Fedora BTRFS Rollback Feature.

    + +

    More generally, if you want to use BTRFS to roll back changes made by +dpkg/rpm, you have to carefully set up the partition layout so that +the files laid out by dpkg/rpm are installed in a subvolume to +snapshot.

    + +

    This problem in many ways is addressed by the changes OSTree forces, +such as putting all local state in /var (e.g. /usr/local -> +/var/usrlocal). Then one can BTRFS snapshot /usr. This gets pretty +far, except handling /etc is messy. This is something OSTree does +well.

    + +

    In general, if one really tries to flesh out the BTRFS approach, a +nontrivial middle layer of code between dpkg/rpm and BTRFS (or deep +awareness of BTRFS in dpkg/rpm itself) will be required. A good +example of this is the snapper.io project.

    + +

    The OSTree author believes that having total freedom at the block +storage layer is better for general purpose operating systems. For +example, the ability to choose dm-crypt per deployment is quite useful; +not every site wants to pay the performance penalty. One can choose +LVM or not, etc.

    + +

    Where applicable, OSTree does take advantage of copy-on-write/reflink +features offered by the kernel for /etc. It uses the now generic +ioctl(FICLONE) and copy_file_range().

    + +

    Another major distinction between the default OSTree usage and package managers +is whether updates are “online” or “offline” by default. The default OSTree +design writes updates into a new root, leaving the running system unchanged. +This means preparing updates is completely non-disruptive and safe - if the +system runs out of disk space in the middle, it’s easy to recover. However, +there is work in the rpm-ostree +project to support online updates as well.

    + +

    OSTree supports using “bare-user” repositories, which do not require +root to use. Using a filesystem-level layer without root is more +difficult and would likely require a setuid helper or privileged service.

    + +

    Finally, see the next portion around ChromiumOS for why a hybrid but +integrated package/image system improves on this.

    +

    + + + ChromiumOS updater + + +

    + + +

    Many people who look at OSTree are most interested in using +it as an updater for embedded or fixed-purpose systems, similar to use cases +from the ChromiumOS updater.

    + +

    The ChromiumOS approach uses two partitions that are swapped via the +bootloader. It has a very network-efficient update protocol, using a +custom binary delta scheme between filesystem snapshots.

    + +

    This model even allows for switching filesystem types in an update.

    + +

    A major downside of this approach is that the OS size is doubled on +disk always. In contrast, OSTree uses plain Unix hardlinks, which +means it essentially only requires disk space proportional to the +changed files, plus some small fixed overhead.

    + +

    This means with OSTree, one can easily have more than two trees +(deployments). Another example is that the system OSTree repository +could also be used for application containers.

    + +

    Finally, the author of OSTree believes that what one really wants for +many cases is image replication with the ability to layer on some +additional components (e.g. packages) - a hybrid model. This is what +rpm-ostree is aiming +to support.

    +

    + + + Ubuntu Image Based Updates + + +

    + + +

    See https://wiki.ubuntu.com/ImageBasedUpgrades. Very architecturally +similar to ChromeOS, although more interesting is discussion for +supporting package installation on top, similar to +rpm-ostree package layering.

    +

    + + + Clear Linux Software update + + +

    + + +

    The +Clear Linux Software update +system is not very well documented. +This mailing list post +has some reverse-engineered design documentation.

    + +

    Like OSTree static deltas, it also uses bsdiff for network efficiency.

    + +

    More information will be filled in here over time. The OSTree author +believes that at the moment, the “CL updater” is not truly atomic in +the sense that because it applies updates live, there is a window +where the OS root may be inconsistent.

    +

    + + + casync + + +

    + + +

    The systemd casync project is +relatively new. Currently, it is more of a storage library, and doesn’t +support higher level logic for things like GPG signatures, versioning +information, etc. This is mostly the OstreeRepo layer. Moving up to +the OstreeSysroot level - things like managing the bootloader +configuration, and most importantly implementing correct merging for /etc +are missing. casync also is unaware of SELinux.

    + +

    OSTree is really today a shared library, and has been for quite some time. +This has made it easy to build higher level projects such as +rpm-ostree which has quite +a bit more, such as a DBus API and other projects consume that, such as +Cockpit.

    + +

    A major issue with casync today is that it doesn’t support garbage collection +on the server side. OSTree’s GC works symmetrically on the server and client +side.

    + +

    Broadly speaking, casync is a twist on the dual partition approach, and +shares the general purpose disadvantages of those.

    +

    + + + Mender.io + + +

    + + +

    Mender.io is another implementation of the dual +partition approach.

    +

    + + + OLPC update + + +

    + + +

    OSTree is basically a generalization of olpc-update, except using +plain HTTP instead of rsync. OSTree has the notion of separate trees +that one can track independently or parallel install, while still +sharing storage via the hardlinked repository, whereas olpc-update +uses version numbers for a single OS.

    + +

    OSTree has built-in plain old HTTP replication which can be served +from a static webserver, whereas olpc-update uses rsync (more server +load, but more efficient on the network side). The OSTree solution to +improving network bandwidth consumption is via static deltas.

    + +

    See +this comment +for a comparison.

    +

    + + + NixOS / Nix + + +

    + + +

    See NixOS. It was a very influential project for OSTree. +NixOS and OSTree both support the idea of independent “roots” that are bootable.

    + +

    In NixOS, files in a package are accessed by a path depending on the checksums +of package inputs (build dependencies) - see +Nix store. +However, OSTree uses a commit/deploy model - it isn’t tied to any particular +directory layout, and you can put whatever data you want inside an OSTree, for +example the standard FHS layout. A both positive and negative of the Nix model +is that a change in the build dependencies (e.g. being built with a newer gcc), +requires a cascading rebuild of everything. It’s good because it makes it easy +to do massive system-wide changes such as gcc upgrades, and allows installing +multiple versions of packages at once. However, a security update to e.g. glibc +forces a rebuild of everything from scratch, and so Nix is not practical at +scale. OSTree supports using a build system that just rebuilds individual +components (packages) as they change, without forcing a rebuild of their +dependencies.

    + +

    Nix automatically detects runtime package dependencies by scanning content for +hashes. OSTree only supports only system-level images, and doesn’t do dependency +management. Nix can store arbitrary files, using nix-store --add, but, more +commonly, paths are added as the result of running a derivation file generated +using the Nix language. OSTree is build-system agnostic; filesystem trees are +committed using a simple C API, and this is the only way to commit files.

    + +

    OSTree automatically shares the storage of identical data using hard links into +a content-addressed store. Nix can deduplicate using hard links as well, using +the auto-optimise-store option, but this is not on by default, and Nix does not +guarantee that all of its files are in the content-addressed store. OSTree +provides a git-like command line interface for browsing the content-addressed +store, while Nix does not have this functionality.

    + +

    Nix used to use the immutable bit to prevent modifications to /nix/store, but +now it uses a read-only bind mount. The bind mount can be privately remounted, +allowing per-process privileged write access. OSTree uses the immutable +bit on the root of the deployment, and mounts /usr as read-only.

    + +

    NixOS supports switching OS images on-the-fly, by maintaining both booted-system +and current-system roots. It is not clear how well this approach works. OSTree +currently requries a reboot to switch images.

    + +

    Finally, NixOS supports installing user-specific packages from trusted +repositories without requiring root, using a trusted daemon. +Flatpak, based on OSTree, similarly has a +policykit-based system helper that allows you to authenticate via polkit to +install into the system repository.

    +

    + + + Solaris IPS + + +

    + + +

    See +Solaris IPS. Broadly, +this is a similar design as to a combination of BTRFS+RPM/deb. There +is a bootloader management system which combines with the snapshots. +It’s relatively well thought through - however, it is a client-side +system assembly. If one wants to image servers and replicate +reliably, that’d be a different system.

    +

    + + + Google servers (custom rsync-like approach, live updates) + + +

    + + +

    This paper talks about how Google was (at least at one point) managing +updates for the host systems for some servers: +Live Upgrading Thousands of Servers from an Ancient Red Hat Distribution to 10 Year Newer Debian Based One (USENIX LISA 2013)

    +

    + + + Conary + + +

    + + +

    See +Conary Updates and Rollbacks. If +rpm/dpkg are like CVS, Conary is closer to Subversion. It’s not bad, +but e.g. its rollback model is rather ad-hoc and not atomic. It also +is a fully client side system and doesn’t have an image-like +replication with deltas.

    +

    + + + bmap + + +

    + + +

    See +bmap. +A tool for optimized copying of disk images. Intended for offline use, +so not directly comparable.

    +

    + + + Git + + +

    + + +

    Although OSTree has been called “Git for Binaries”, and the two share the idea +of a hashed content store, the implementation details are quite different. +OSTree supports extended attributes and uses SHA256 instead of Git’s SHA1. It +“checks out” files via hardlinks, rather than copying, and thus requires the +checkout to be immutable. At the moment, OSTree commits may have at most one +parent, as opposed to Git which allows an arbitrary number. Git uses a +smart-delta protocol for updates, while OSTree uses 1 HTTP request per changed +file, or can generate static deltas.

    +

    + + + Conda + + +

    + + +

    Conda is an “OS-agnostic, system-level binary +package manager and ecosystem”; although most well-known for its accompanying +Python distribution anaconda, its scope has been expanding quickly. The package +format is very similar to well-known ones such as RPM. However, unlike typical +RPMs, the packages are built to be relocatable. Also, the package manager runs +natively on Windows. Conda’s main advantage is its ability to install +collections of packages into “environments” by unpacking them all to the same +directory. Conda reduces duplication across environments using hardlinks, +similar to OSTree’s sharing between deployments (although Conda uses package / +file path instead of file hash). Overall, it is quite similar to rpm-ostree in +functionality and scope.

    +

    + + + rpm-ostree + + +

    + + +

    This builds on top of ostree to support building RPMs into OSTree images, and +even composing RPMs on-the-fly using an overlay filesystem. It is being +developed by Fedora, Red Hat, and CentOS as part of Project Atomic.

    +

    + + + GNOME Continuous + + +

    + + +

    This is a service that incrementally rebuilds and tests GNOME on every commit. +The need to make and distribute snapshots for this system was the original +inspiration for ostree.

    +

    + + + Docker + + +

    + + +

    It makes sense to compare OSTree and Docker as far as wire formats +go. OSTree is not itself a container tool, but can be used as a +transport/storage format for container tools.

    + +

    Docker has (at the time of this writing) two format versions (v1 and +v2). v1 is deprecated, so we’ll look at format version 2.

    + +

    A Docker image is a series of layers, and a layer is essentially JSON +metadata plus a tarball. The tarballs capture changes between layers, +including handling deleting files in higher layers.

    + +

    Because the payload format is just tar, Docker hence captures +(numeric) uid/gid and xattrs.

    + +

    This “layering” model is an interesting and powerful part of Docker, +allowing different images to reference a shared base. OSTree doesn’t +implement this natively, but it’s not difficult to implement in higher +level tools. For example in +flatpak, there’s a concept of a +SDK and runtime, and it would make a lot of sense for the SDK to +depend on the runtime, to avoid clients downloading data twice (even +if it’s deduplicated on disk).

    + +

    That gets to an advantage of OSTree over Docker; OSTree checksums +individual files (not tarballs), and uses this for deduplication. +Docker (natively) only shares storage via layering.

    + +

    The biggest feature OSTree has over Docker though is support for +(static) deltas, and even without pre-configured static deltas, the +archive format has “natural” deltas. Particularly for a “base +operating system”, one really wants on-wire deltas. It’d likely be +possible to extend Docker with this concept.

    + +

    A core challenge both share is around metadata (particularly signing) +and search/discovery (the ostree summary file doesn’t scale very +well).

    + +

    One major issue Docker has is that it checksums compressed data, +and furthermore the tar format is flexible, with multiple ways to represent data, +making it hard to impossible to reassemble and verify from on-disk state. +The tarsum effort +was intended to address this, but it was not adopted in the end for v2.

    + + + +

    The Balena project forks Docker and aims +to even use Docker/OCI format for the root filesystem, and adds wire deltas +using librsync. See also discussion on libostree-list.

    +

    + + + Torizon Platform + + +

    + + +

    Torizon is an open-source +software platform that simplifies the development and maintenance of embedded +Linux software. It is designed to be used out-of-the-box on devices requiring +high reliability, allowing you to focus on your application and not on building +and maintaining the operating system.

    +

    + + + Torizon OS + + +

    + + +

    The platform OS - Torizon OS - +is a minimal OS with a Docker runtime and libostree + Aktualizr. The main goal +of this system is to allow application developers to use containers, while the +maintainers of Torizon OS focus on the base system updates.

    +

    + + + TorizonCore Builder + + +

    + + +

    Since the Torizon OS is meant as a binary distribution, OS customization is +made easier with TorizonCore Builder, +as the tool abstracts the handling of OSTree concepts from the final users.

    +

    + + + Torizon Cloud + + +

    + + +

    Torizon Cloud +is a hosted OTA update system that provides OS updates to Torizon OS using +OSTree and Aktualizr.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/repo/index.html b/repo/index.html new file mode 100644 index 0000000000..7db107e754 --- /dev/null +++ b/repo/index.html @@ -0,0 +1,478 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Anatomy of an OSTree repository | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Anatomy of an OSTree repository + + +

    + + +
      +
    1. Core object types and data model
        +
      1. Commit objects
      2. +
      3. Dirtree objects
      4. +
      5. Dirmeta objects
      6. +
      7. Content objects
      8. +
      9. Xattrs objects
      10. +
      +
    2. +
    3. Repository types and locations
        +
      1. Refs
      2. +
      3. The summary file
      4. +
      +
    4. +
    + + +

    + + + Core object types and data model + + +

    + + +

    OSTree is deeply inspired by git; the core layer is a userspace +content-addressed versioning filesystem. It is worth taking some time +to familiarize yourself with +Git Internals, as this +section will assume some knowledge of how git works.

    + +

    Its object types are similar to git; it has commit objects and content +objects. Git has “tree” objects, whereas OSTree splits them into +“dirtree” and “dirmeta” objects. But unlike git, OSTree’s checksums +are SHA256. And most crucially, its content objects include uid, gid, +and extended attributes (but still no timestamps).

    +

    + + + Commit objects + + +

    + + +

    A commit object contains metadata such as a timestamp, a log +message, and most importantly, a reference to a +dirtree/dirmeta pair of checksums which describe the root +directory of the filesystem. +Also like git, each commit in OSTree can have a parent. It is +designed to store a history of your binary builds, just like git +stores a history of source control. However, OSTree also makes +it easy to delete data, under the assumption that you can +regenerate it from source code.

    +

    + + + Dirtree objects + + +

    + + +

    A dirtree contains a sorted array of (filename, checksum) +pairs for content objects, and a second sorted array of +(filename, dirtree checksum, dirmeta checksum), which are +subdirectories. This type of object is stored as files +ending with .dirtree in the objects directory.

    +

    + + + Dirmeta objects + + +

    + + +

    In git, tree objects contain the metadata such as permissions +for their children. But OSTree splits this into a separate +object to avoid duplicating extended attribute listings. +These type of objects are stored as files ending with .dirmeta +in the objects directory.

    +

    + + + Content objects + + +

    + + +

    Unlike the first three object types which are metadata, designed to be +mmap()ed, the content object has a separate internal header and +payload sections. The header contains uid, gid, mode, and symbolic +link target (for symlinks), as well as extended attributes. After the +header, for regular files, the content follows. These parts together +form the SHA256 hash for content objects. The content type objects in +this format exist only in archive OSTree repositories. Today the +content part is gzip’ed and the objects are stored as files ending +with .filez in the objects directory. Because the SHA256 hash is +formed over the uncompressed content, these files do not match the +hash they are named as.

    + +

    The OSTree data format intentionally does not contain timestamps. The reasoning +is that data files may be downloaded at different times, and by different build +systems, and so will have different timestamps but identical physical content. +These files may be large, so most users would like them to be shared, both in +the repository and between the repository and deployments.

    + +

    This could cause problems with programs that check if files are out-of-date by +comparing timestamps. For Git, the logical choice is to not mess with +timestamps, because unnecessary rebuilding is better than a broken tree. +However, OSTree has to hardlink files to check them out, and commits are assumed +to be internally consistent with no build steps needed. For this reason, OSTree +acts as though all timestamps are set to time_t 0, so that comparisons will be +considered up-to-date. Note that for a few releases, OSTree used 1 to fix +warnings such as GNU Tar emitting “implausibly old time stamp” with 0; however, +until we have a mechanism to transition cleanly to 1, for compatibilty OSTree +is reverted to use zero again.

    +

    + + + Xattrs objects + + +

    + + +

    In some repository modes (e.g. bare-split-xattrs), xattrs are stored on the +side of the content objects they refer to. This is done via two dedicated +object types, file-xattrs and file-xattrs-link.

    + +

    file-xattrs store xattrs data, encoded as GVariant. Each object is keyed by +the checksum of the xattrs content, allowing for multiple references.

    + +

    file-xattrs-link are hardlinks which are associated to file objects. +Each object is keyed by the same checksum of the corresponding file +object. The target of the hardlink is an existing file-xattrs object. +In case of reaching the limit of too many links, this object could be +a plain file too.

    +

    + + + Repository types and locations + + +

    + + +

    Also unlike git, an OSTree repository can be in one of five separate +modes: bare, bare-split-xattrs, bare-user, bare-user-only, and +archive.

    + +

    A bare repository is one where content files are just stored as regular +files; it’s designed to be the source of a “hardlink farm”, where each +operating system checkout is merely links into it. If you want to store files +owned by e.g. root in this mode, you must run OSTree as root.

    + +

    The bare-split-xattrs mode is similar to the above one, but it does store +xattrs as separate objects. This is meant to avoid conflicts with +kernel-enforced constraints (e.g. on SELinux labels) and with other softwares +that may perform ephemeral changes to xattrs (e.g. container runtimes).

    + +

    The bare-user mode is a later addition that is like bare in that +files are unpacked, but it can (and should generally) be created as +non-root. In this mode, extended metadata such as owner uid, gid, and +extended attributes are stored in extended attributes under the name +user.ostreemeta but not actually applied. +The bare-user mode is useful for build systems that run as non-root +but want to generate root-owned content, as well as non-root container +systems.

    + +

    The bare-user-only mode is a variant to the bare-user mode. Unlike +bare-user, neither ownership nor extended attributes are stored. These repos +are meant to to be checked out in user mode (with the -U flag), where this +information is not applied anyway. Hence this mode may lose metadata. +The main advantage of bare-user-only is that repos can be stored on +filesystems which do not support extended attributes, such as tmpfs.

    + +

    In contrast, the archive mode is designed for serving via plain +HTTP. Like tar files, it can be read/written by non-root users.

    + +

    On an OSTree-deployed system, the “system repository” is /ostree/repo. It can +be read by any uid, but only written by root. The ostree command will by +default operate on the system repository; you may provide the --repo argument +to override this, or set the $OSTREE_REPO environment variable.

    +

    + + + Refs + + +

    + + +

    Like git, OSTree uses the terminology “references” (abbreviated +“refs”) which are text files that name (refer to) particular +commits. See the +Git Documentation +for information on how git uses them. Unlike git though, it doesn’t +usually make sense to have a “main” branch. There is a convention +for references in OSTree that looks like this: +exampleos/buildmain/x86_64-runtime and +exampleos/buildmain/x86_64-devel-debug. These two refs point to +two different generated filesystem trees. In this example, the +“runtime” tree contains just enough to run a basic system, and +“devel-debug” contains all of the developer tools and debuginfo.

    + +

    The ostree supports a simple syntax using the caret ^ to refer to +the parent of a given commit. For example, +exampleos/buildmain/x86_64-runtime^ refers to the previous build, +and exampleos/buildmain/x86_64-runtime^^ refers to the one before +that.

    +

    + + + The summary file + + +

    + + +

    A later addition to OSTree is the concept of a “summary” file, created +via the ostree summary -u command. This was introduced for a few +reasons. A primary use case is to be compatible with +Metalink, which requires a +single file with a known checksum as a target.

    + +

    The summary file primarily contains two mappings:

    + +
      +
    • A mapping of the refs and their checksums, equivalent to fetching +the ref file individually
    • +
    • A list of all static deltas, along with their metadata checksums
    • +
    + +

    This currently means that it grows linearly with both items. On the +other hand, using the summary file, a client can enumerate branches.

    + +

    Further, fetching the summary file over e.g. pinned TLS creates a strong +end-to-end verification of the commit or static delta.

    + +

    The summary file can also be GPG signed (detached). This is currently +the only way to provide GPG signatures (transitively) on deltas.

    + +

    If a repository administrator creates a summary file, they must +thereafter run ostree summary -u to update it whenever a ref is +updated or a static delta is generated.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/repository-management/index.html b/repository-management/index.html new file mode 100644 index 0000000000..f016fd7814 --- /dev/null +++ b/repository-management/index.html @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Managing content in OSTree repositories | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Managing content in OSTree repositories + + +

    + + +
      +
    1. Mirroring repositories
    2. +
    3. Separate development vs release repositories
    4. +
    5. Promoting content along OSTree branches - “buildmain”, “smoketested”
    6. +
    7. Promoting content between OSTree repositories
    8. +
    9. Derived data - static deltas and the summary file
    10. +
    11. Pruning our build and dev repositories
    12. +
    13. Generating “scratch” deltas for efficient initial downloads
    14. +
    + + + +

    Once you have a build system going, if you actually want client +systems to retrieve the content, you will quickly feel a need for +“repository management”.

    + +

    The command line tool ostree does cover some core functionality, but +doesn’t include very high level workflows. One reason is that how +content is delivered and managed has concerns very specific to the +organization. For example, some operating system content vendors may +want integration with a specific errata notification system when +generating commits.

    + +

    In this section, we will describe some high level ideas and methods +for managing content in OSTree repositories, mostly independent of any +particular model or tool. That said, there is an associated upstream +project ostree-releng-scripts +which has some scripts that are intended to implement portions of +this document.

    + +

    Another example of software which can assist in managing OSTree +repositories today is the Pulp Project, +which has a +Pulp OSTree plugin.

    +

    + + + Mirroring repositories + + +

    + + +

    It’s very common to want to perform a full or partial mirror, in +particular across organizational boundaries (e.g. an upstream OS +provider, and a user that wants offline and faster access to the +content). OSTree supports both full and partial mirroring of the base +archive content, although not yet of static deltas.

    + +

    To create a mirror, first create an archive repository (you don’t +need to run this as root), then add the upstream as a remote, then use +pull --mirror.

    + +
    ostree --repo=repo init --mode=archive
    +ostree --repo=repo remote add exampleos https://exampleos.com/ostree/repo
    +ostree --repo=repo pull --mirror exampleos:exampleos/x86_64/standard
    +
    + +

    You can use the --depth=-1 option to retrieve all history, or a +positive integer like 3 to retrieve just the last 3 commits.

    + +

    See also the rsync-repos script in +ostree-releng-scripts.

    +

    + + + Separate development vs release repositories + + +

    + + +

    By default, OSTree accumulates server side history. This is actually +optional in that your build system can (using the API) write a commit +with no parent. But first, we’ll investigate the ramifications of +server side history.

    + +

    Many content vendors will want to separate their internal development +with what is made public to the world. Therefore, you will want (at +least) two OSTree repositories, we’ll call them “dev” and “prod”.

    + +

    To phrase this another way, let’s say you have a continuous delivery +system which is building from git and committing into your “dev” +OSTree repository. This might happen tens to hundreds of times per +day. That’s a substantial amount of history over time, and it’s +unlikely most of your content consumers (i.e. not developers/testers) +will be interested in all of it.

    + +

    The original vision of OSTree was to fulfill this “dev” role, and in +particular the “archive” format was designed for it.

    + +

    Then, what you’ll want to do is promote content from “dev” to “prod”. +We’ll discuss this later, but first, let’s talk about promotion +inside our “dev” repository.

    +

    + + + Promoting content along OSTree branches - “buildmain”, “smoketested” + + +

    + + +

    Besides multiple repositories, OSTree also supports multiple branches +inside one repository, equivalent to git’s branches. We saw in an +earlier section an example branch name like +exampleos/x86_64/standard. Choosing the branch name for your “prod” +repository is absolutely critical as client systems will reference it. +It becomes an important part of your face to the world, in the same +way the “main” branch in a git repository is.

    + +

    But with your “dev” repository internally, it can be very useful to +use OSTree’s branching concepts to represent different stages in a +software delivery pipeline.

    + +

    Deriving from exampleos/x86_64/standard, let’s say our “dev” +repository contains exampleos/x86_64/buildmain/standard. We choose the +term “buildmain” to represent something that came straight from git +main. It may not be tested very much.

    + +

    Our next step should be to hook up a testing system (Jenkins, +Buildbot, etc.) to this. When a build (commit) passes some tests, we +want to “promote” that commit. Let’s create a new branch called +smoketested to say that some basic sanity checks pass on the +complete system. This might be where human testers get involved, for +example.

    + +

    This is a basic way to “promote” the buildmain commit that passed testing:

    + +
    ostree commit -b exampleos/x86_64/smoketested/standard -s 'Passed tests' --tree=ref=aec070645fe53...
    +
    + +

    Here we’re generating a new commit object (perhaps include in the commit +log links to build logs, etc.), but we’re reusing the content from the buildmain +commit aec070645fe53 that passed the smoketests.

    + +

    For a more sophisticated implementation of this model, see the +do-release-tags +script, which includes support for things like propagating version +numbers across commit promotion.

    + +

    We can easily generalize this model to have an arbitrary number of +stages like exampleos/x86_64/stage-1-pass/standard, +exampleos/x86_64/stage-2-pass/standard, etc. depending on business +requirements and logic.

    + +

    In this suggested model, the “stages” are increasingly expensive. The +logic is that we don’t want to spend substantial time on e.g. network +performance tests if something basic like a systemd unit file fails on +bootup.

    +

    + + + Promoting content between OSTree repositories + + +

    + + +

    Now, we have our internal continuous delivery stream flowing, it’s +being tested and works. We want to periodically take the latest +commit on exampleos/x86_64/stage-3-pass/standard and expose it in +our “prod” repository as exampleos/x86_64/standard, with a much +smaller history.

    + +

    We’ll have other business requirements such as writing release notes +(and potentially putting them in the OSTree commit message), etc.

    + +

    In Build Systems we saw how the +pull-local command can be used to migrate content from the “build” +repository (in bare-user mode) into an archive repository for +serving to client systems.

    + +

    Following this section, we now have three repositories, let’s call +them repo-build, repo-dev, and repo-prod. We’ve been pulling +content from repo-build into repo-dev (which involves gzip +compression among other things since it is a format change).

    + +

    When using pull-local to migrate content between two archive +repositories, the binary content is taken unmodified. Let’s go ahead +and generate a new commit in our prod repository:

    + +
    checksum=$(ostree --repo=repo-dev rev-parse exampleos/x86_64/stage-3-pass/standard`)
    +ostree --repo=repo-prod pull-local repo-dev ${checksum}
    +ostree --repo=repo-prod commit -b exampleos/x86_64/standard \
    +       -s 'Release 1.2.3' --add-metadata-string=version=1.2.3 \
    +	   --tree=ref=${checksum}
    +
    + +

    There are a few things going on here. First, we found the latest +commit checksum for the “stage-3 dev”, and told pull-local to copy +it, without using the branch name. We do this because we don’t want +to expose the exampleos/x86_64/stage-3-pass/standard branch name in +our “prod” repository.

    + +

    Next, we generate a new commit in prod that’s referencing the exact +binary content in dev. If the “dev” and “prod” repositories are on +the same Unix filesystem, (like git) OSTree will make use of hard +links to avoid copying any content at all - making the process very +fast.

    + +

    Another interesting thing to notice here is that we’re adding an +version metadata string to the commit. This is an optional +piece of metadata, but we are encouraging its use in the OSTree +ecosystem of tools. Commands like ostree admin status show it by +default.

    +

    + + + Derived data - static deltas and the summary file + + +

    + + +

    As discussed in Formats, the archive repository we +use for “prod” requires one HTTP fetch per client request by default. +If we’re only performing a release e.g. once a week, it’s appropriate +to use “static deltas” to speed up client updates.

    + +

    So once we’ve used the above command to pull content from repo-dev +into repo-prod, let’s generate a delta against the previous commit:

    + +
    ostree --repo=repo-prod static-delta generate exampleos/x86_64/standard
    +
    + +

    We may also want to support client systems upgrading from two +commits previous.

    + +
    ostree --repo=repo-prod static-delta generate --from=exampleos/x86_64/standard^^ --to=exampleos/x86_64/standard
    +
    + +

    Generating a full permutation of deltas across all prior versions can +get expensive, and there is some support in the OSTree core for static +deltas which “recurse” to a parent. This can help create a model +where clients download a chain of deltas. Support for this is not +fully implemented yet however.

    + +

    Regardless of whether or not you choose to generate static deltas, +you should update the summary file:

    + +
    ostree --repo=repo-prod summary -u
    +
    + +

    (Remember, the summary command cannot be run concurrently, so this + should be triggered serially by other jobs).

    + +

    There is some more information on the design of the summary file in +Repo.

    +

    + + + Pruning our build and dev repositories + + +

    + + +

    First, the OSTree author believes you should not use OSTree as a +“primary content store”. The binaries in an OSTree repository should +be derived from a git repository. Your build system should record +proper metadata such as the configuration options used to generate the +build, and you should be able to rebuild it if necessary. Art assets +should be stored in a system that’s designed for that +(e.g. Git LFS).

    + +

    Another way to say this is that five years down the line, we are +unlikely to care about retaining the exact binaries from an OS build +on Wednesday afternoon three years ago.

    + +

    We want to save space and prune our “dev” repository.

    + +
    ostree --repo=repo-dev prune --refs-only --keep-younger-than="6 months ago"
    +
    + +

    That will truncate the history older than 6 months. Deleted commits +will have “tombstone markers” added so that you know they were +explicitly deleted, but all content in them (that is not referenced by +a still retained commit) will be garbage collected.

    +

    + + + Generating “scratch” deltas for efficient initial downloads + + +

    + + +

    In general, the happy path for OSTree downloads is via static deltas. +If you are in a situation where you want to download an OSTree +commit from an uninitialized repo (or one with unrelated history), you +can generate “scratch” (aka --empty deltas) which bundle all +objects for that commit.

    + +

    The tradeoff here is increasing server disk space in return +for many fewer client HTTP requests.

    + +

    For example:

    + +
    $ ostree --repo=/path/to/repo static-delta generate --empty --to=exampleos/x86_64/testing-devel
    +$ ostree --repo=/path/to/repo summary -u
    +
    + +

    After that, clients fetching that commit will prefer fetching the “scratch” delta if they don’t have the original ref.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/var/index.html b/var/index.html new file mode 100644 index 0000000000..e4a43dcb9c --- /dev/null +++ b/var/index.html @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +OSTree and /var handling | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + OSTree and /var handling + + +

    + + +
      +
    1. OSTree and /var handling
        +
      1. Default commit/image /var handling
      2. +
      3. Pitfalls
      4. +
      5. Examples
          +
        1. debs/RPMs which drop files into /opt (i.e. /var/opt)
        2. +
        3. Apache default content in /var/www/html
        4. +
        5. User home directories and databases
        6. +
        7. /var/lib/containers
        8. +
        9. dnf /var/lib/dnf/history.sqlite
        10. +
        +
      6. +
      7. Previous ostree /var and tmpfiles.d /usr/share/factory/var
      8. +
      +
    2. +
    + + +

    + + + Default commit/image /var handling + + +

    + + +

    As of OSTree 2024.3, when a commit is “deployed” (queued to boot), +the initial content of /var in a commit will be placed into the +“stateroot” (default var) if the stateroot var is empty.

    + +

    The semantics of this are intended to match that of Docker “volumes”; +consider that ostree systems have the equivalent of +VOLUME /var +by default.

    + +

    It is still strongly recommended to use systemd tmpfiles.d snippets +to populate directory structure and the like in /var on firstboot, +because this is more resilent.

    + +

    Even better, use StateDirectory= for systemd units.

    +

    + + + Pitfalls + + +

    + + +

    On subsequent upgrades, normally /var would not be empty anymore +(as it’s typically expected that basics like /var/tmp etc. are created, + if not also other local state such as /var/log etc.). Hence, +no updates from the commit/container will be applied.

    + +

    To be clear then:

    + +
      +
    • Any files which already exist will not be updated.
    • +
    • Any files which are deleted in the new version will not be deleted on existing systems.
    • +
    +

    + + + Examples + + +

    + +

    + + + debs/RPMs which drop files into /opt (i.e. /var/opt) + + +

    + + +

    The default OSTree “strict” layout has /opt be a symlink to /var/opt. +Including any packaged content that “straddles” /usr and /var (i.e. /var/opt) +will over time cause drift because changes in the package will not be reflected on disk.

    + +

    For situations like this, it’s strongly recommended to enable either +composefs.enabled = true or the root.transient = true option for ostree-prepare-root.conf +and change ensure your commit/container image has /opt as a plain directory. In the former case, +content in /opt will be immutable at runtime, the same as everything else in /usr. +In the latter case content it will be writable but transient.

    + +

    There’s also a currently-experimental ../man/ostree-state-overlay@.service.xml +which can manage stateful writable overlays for individual mounts.

    +

    + + + Apache default content in /var/www/html + + +

    + + +

    In general, such static content would much better live in /usr - or even better, in an application container.

    +

    + + + User home directories and databases + + +

    + + +

    The semantics here are likely OK for the use case of “default users”.

    +

    + + + /var/lib/containers + + +

    + + +

    Pulling container images into OSTree commits like this would be a bad idea; similar problems as RPM content.

    +

    + + + dnf /var/lib/dnf/history.sqlite + + +

    + + +

    For $reasons dnf has its own database for state distinct from the RPM database, which on rpm-ostree systems is in /usr/share/rpm (under the read-only bind mount, managed by OS updates).

    + +

    In an image/container-oriented flow, we don’t really care about this database which mainly holds things like “was this package user installed”. This data could move to /usr.

    +

    + + + Previous ostree /var and tmpfiles.d /usr/share/factory/var + + +

    + + +

    From OSTree versions 2023.8 to v2024.3 the /usr/lib/tmpfiles.d/ostree-tmpfiles.conf file included this snippet:

    + +
    # Automatically propagate all /var content from /usr/share/factory/var;
    +# the ostree-container stack is being changed to do this, and we want to
    +# encourage ostree use cases in general to follow this pattern.
    +C+! /var - - - - -
    +
    + +

    Until version 0.13.2 of the ostree-ext project, content in /var in fetched container images is moved to /usr/share/factory/var, but this no longer happens when targeting ostree v2024.3.

    + +

    Together, this will have the semantic that on OS updates, on the next boot (early in boot), any new files/directories will be copied. For more information on this, see man tmpfiles.d.

    + +

    This has been reverted, and the semantics defer to the above ostree semantic.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + +
    x 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 A+5i9m literal 0 HcmV?d00001 diff --git a/assets/images/search.svg b/assets/images/search.svg new file mode 100644 index 0000000000..421ca4df01 --- /dev/null +++ b/assets/images/search.svg @@ -0,0 +1 @@ +Search diff --git a/assets/images/small-image.jpg b/assets/images/small-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5bf58a94932c306eaf01dce6561ef37afa513a11 GIT binary patch literal 44128 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�sSMF&Mw z%(FzStU=&Cnh;606n)~Q>q}b{z50Gs!j^Y336jQ(=j@bSZs01? zx;4eFJ&6vp$q1; zoV2Y|t)aO#E}>vZLxB`Us;eo4>ozZux~^uXa!ZFlejm<-4sG9Z+ zL*IT{Y{er36K@AgdS{p)y5gJbZ;s`CBA3XLvyWDmvWKOxVEnqRO= zB*2M#@=cB9WK|n54um7ezkiom!?|SC!pi=0$|P@8?01Npy1`}=B>iE%WVD~lAi)A- zx~?Jdie!r-*>)at2MA)qk1&((eEU6c3qVuF^o3*dw_}vnM6Lr(nm8y)Esm;ZUIv`I zK&8fwr(yp1`6S91yA>yCh0AZW3JO3`IUUzn%OJN9-qFAp}a4f_PuwzCmiV8w$v&c8M^^obZR@zGNxm|S@ z*X}v9cSVES;v2KyVmzJIZ4ITrom{pdTaf|>>Nrs0%%dXgQpHQ<&?(Xu7P_VH-_;i! zPFTQPCw-mqW4i4(K`d@9B|>2alKH`Z#fY)rUFdd|=5fVl4lP>6=_8qYR*Lj}DRh6= z^N1smTJ?ivWGcUc-z=txUlf{eWSSCHNIWDenOP7BZDDt#>CUCWnrQuPD5*huvwEAC z$)nk-VEgfaYcgh~)af*YfCby%6zg~bX#?i54W#buZX7nR>3hYvnewNOpNkzEhj#_teb7D2@vX`(jpWsD-y!I@O~_iikg7bZVL!!F+8?Ltujb zhPLhI$b0^NeOITTIBb8d9;5AWcccvhlrX>jGo$RVGg&K1!#6>ts5cdP zwY_q|ql^S3hE;#yEMIOYWc*|&(=B+1)%2F%r5ztdOWMJ=}S#rlww}ZCvgbdZq>+&tYhP~Bc1MIU-9S(+-x2U zTASA0;#17ofpI(|#b!v{0|xJwNex2LG-ZHF^#!-cFIipKy1SI)JkZ zTu=q@$!ADQefI3vXs9cDYTzG$HrG^F{r8jS;jPo@M0I60>*ay-U5S-*ys+x){~kXV zuU1j{kL*bT_@vwYEr!=$;q2Y`0HN@+Xh-) zzrXsjy}}TG%^01|IZJI$-X&NsK&-rGuK-b>w|PIqACk3RL1Q_Q80TLZt5}o1-B9^Z zrz*D7+~-;sEe#W%Nzx7HsKmL=C$q^68{seR%wH5o6_Nn@GxP~lU9>R2dxXT_18+mZ!sF%!&xC|T03pgVhec4vxG?_bddqk~i(Db*Amv+gkGbNZ>S`83yKPcK^4A9T!>;l!e*n;t8b=&_f zO&OEtz~pY?{j}^SjvRU@m%O!*DH3$xYtbBd;`*WgZ=LXE0O8%g|2p8WWxIj~eD(8! zt9QSJJ?afv0%s?(QZwTvKPyZF6&nL979L^$V*WI76CL5J7Cc)maLX>avVKC#Vwt7A z;F1X>iPCqCa0!GuCkLF`HCj|++o zQ?W{p4c?YVi6!26{C_`ic`Tlu?xr*^08ukk0-vGUZDFl)yXb;a_6+#Z+UIFm)v7kODG*zA>Wzz=8P9~l1+0CYf$ zzsJNG@=NPeU}32jK7};>j_7eXH2!giT&Nnzs5uQyIUyEO0vmXpH&N@XeZv5JU#QdS z8QYAn(*jL3+Pyh!06ZlHU-QEe_vx}{!*-t_N?C0TxQ0kkQj%7bn*w(!BWxzKZ8~id zsl_UNLOYQru`ZgIm~}Q=YUXq!v9TLrpS4!1I4>4!nr1)9S!Cd`fK_R^2Hyp_s5Iy_ zX-&tc!G%qZC2i`rdxCJ@r$dk{EG2C?0Er&@lhA8_t~37t1!E>ochcC9sSaJzmXvnX zrwCC4s%|VtOJU47PxEk+h)*1`n_%#!Q#D_sTU2^=PHbkO!Aop)OQ=FY0?AIm8xDh} z5GQGP{#Z?m#Jm3h8P4kK@lNnG8b=%swumR%L6I7P9nC%>;sI5x zO_IL9?#CV+$Sr$PIJD)?~q{iJd$glZ)% z{w**0;@*!D!Xr+&@CdP_mQ)A)eO9l|v8#1D%$FfPl%c0owGLX7w%cmxt%={Z7t`cP zk(y#5bi|#!zZJ26WGc<_mmKb4AC}|rhKpm1V=65#0re|%*dC`?A zDwNmI%39Q-6{LI0d;b8(P4UvVRm_bN=Q_0eIgcxIY&n&PK_H-Q_3hiIo*Y^6Go^k9>nw3nSvQ@X~6MK%>xLQ;@P=T_-9CwHr#g~X$(M_h6kbs+j zAJ~2PzlQXA5?hK0WiBl#DJ`LDP0wXo;NWtDnPt>Cg`U`z%6Zg7r}EuqGi;F14v>-% z04D1@_37n{I(+t*RE*M4W2CJF-Z1NN`d7JEt|bx&$*-;~EW-LJXsWJuXsabQaZP)u zX~y*^5C~PmfYaM^d{}0uLm5)ND8>P_)8#0qnn}`GSOWh5@qANo@?4nF>u#{y3XXFP zOxe&%los~jZ?*J{UT3)k4hzGfnU>kGHa%|{8=-dTZTJv+XzSsDcF;J?SHotJ5dhRRJVwfd?YKeIAX@A zq7MLb#+D>4$KyDaI7)db0kQz=s{SL}xWdnvqVWKYUa7^z?jU9A7Ys8#Tc09Jb;_(Y z2#Hf9$FbNFp>mV4+>CSB2EDIq95yNDG_HPG%u2MR25)wi0Y@w&TcO6+AHF#!AZh5}it`RwR4lb0o-flM&Yt0^KT2&W{z+ z6LIJA$43PuvUAg_35lL6PqR#M=Tn#4NJUpu2ugX%I=-c9zfQON4lDS}Q^@Vaddn=)FeG9)sw?+}!blqF!Ol>~&|*Vtkp!9yBZH|cYtrea|arB&{$ z3JYeEy#ub=xrXB4?gkTF9G0f@_YfXx5+=w>BPl6*TBD=@^6YgbDnAh&Y%P2iK=zd3 z@@7hXGpDvSETu*Qykzt??e^ha!)_;KT(6oljYhA}md#ZxqAPJzab&G(R=rwn)iwhC z@fl2`kQ0-N4bDqBIl1)a7)!Z|0sPvax0F8q6N+vl`$q8FGuE=~xYMeknsiqiT0|u@ z?xigR3y`2d2)+Ey2Dr(`%#odVYK*%^smtest5oPtBo3Y(Nk^w!cfdiF13;EM6IfLj zIF90owEX_5>@c_iD7C|RsRY=|ApRfB;Zwuh%|XjeRb$Dj61ngf6&#qZsB;TzNY!+U z3#e~~-v{Y$QZkgdB!ww6Qc93X2U2bi-EP=Ji=R&~7C(>N%-7 zFE3OpW5j8U8DS+#7t)*c0{;MZ0V$r>lyjNu)z+ca-8HDun0bbwI85a8r#`7Q*SgoU<;R`V@3z_NyymVl)a zI&HAR{1D+&c3a<{V!Im!?aj$8c+16T9BIllHj5d7hABUt$B-$DQw{{_Xq72SvQh{D zk$V+kgTNf--bv3nLVSqplFR%*nGB_(0+G#I$O;$O*xPRS{-;7jPiB~rl#r)Wm+H;l z-IF~e{v!Aa$&a6m zp~VC?q-46fLX`SZ;^T3O zUskaMFo;hB_Z z^m&;ZEvdToI7k%qhgej^YeSk`0R=a>KM1#7@s|;Z6mI6sh_$|}TWMxsykF65{{U!) zkr#sW_DLf|hEw*IUH<@nK56j1D1SCngVEW2Nz2t0B`>sxQK&k*9V!HN$JQ+W0Fz+n ztiK+WJ#L7NPK^4{%Cwb$u-QR9fessyzS#L6lrt?SB<8Ag`oxx_K}9ZnYdHE_DpKEd zDGAg?`ds4fj-=q%KVzrJs%p3zWxJ24TdROMZ!G0%PHU(_qf)5{=$b;@lO8K<8yVy% zsXz|4A9gbrv~6l7TZ`OypG}n9*ltvzy3@=ZNN@)ex=89S4&$yY;PFQ4qKsV@9Ph$#q8m} z{&kVyznS*=;uK=j&BlZj&~3Hrq=KITT96OcYrpUP1r?we!sf}CWmj;x%iN<`_pB5rka@A&t#Y7sT(&y7v9fimiZ%b!U z2)b@`8=dcd*x^)K+m7nA8zhbJX~Y_giL)t@)bh+^Lk@EF5(?BB@ml>)ObE$rJxPDD z)pC07I%Af{kZZ^smq&oL5DzrHSx&ap7}_U$l1*^>k2dcu)Qc zvD1t(OHy}x)bipaXMVEC85yV6V#jxRh*K}azia4 z1#eK5WRzV-@=~q5jj$P+{j@l3nWnhpjImjH3L$AkmRl$b0@o=H*!kNOlRc)g4E)k6 zjz-J~fSOvNrMBX?tTmZP{{TI{>~_KA)7ntbtER|Vx6bzK-v!XA^OF2V9HluGN?Kgz6sbfY8=bXn zu=2u%&O2oGbHv$E(^YbVDfG%A=%7kk($Y|nq6tcc^<5`z_rGFDp40giw;FNLnPR*f z2z_m#rx5Ch0cy68Q>%S}+s_k}l_d5q+$wW&oIj^G<%L{5^Ztc5Eyq} zB+ZjPpxd)0Q=Vp=WNL7JNwI+X1>(EDZ9($z_|lAX7(KeRDv z118jRH6hvU=h?Y&xhpJ!iWK%!AtK}rb^!M}PCLPeSgcc3A-*Wq98)7iR+^#CbSW1* zrAQ?y9u)2C=y34XJ9!_XSHtf4g;y8Zr-)KYgDt{Vm4^1HHM)raTgATQemMP=?A^pz zB}j5J2T4jvMAnLKu7dioM*}S8y3D6ojl_({DYPlHKI2qcht;a!l&D+~PzYD9*6W6s z6ZkSAWjYpX$=pY-t}~4`%*YNVMEZ+w0%7q0Os2h7(VMqKBMrYf92U1nd=a zvWH9>RI>LGsjooy+~1lL0<9Ht;!9?qGC+{mG=NGFNl7Fql&ZxisNVR2J1b^|QRdq> z=Bcd*R23QAy*(|syL3@1uq1#iLA9_ZtAYKBEQ9z$1Ez4(GuG-z3e^(Y<#e0eUmtxBE2cdts#~|O3J4-bm~w@xV`$QU@E0AJmse1N}SzdmDn?{J>Qo~@TpwYUBQ2=k`gNj_^?A@QT6eeWU>C2ScX4mM^EP8?!6|GOn~5>>Yi|0AmX+Bg3+zS3?cX2ON*-sX z(je6*XAIj85&pVFx+M0Sjz+JAW!oy=gnUQW0mO9c;8ce9e8N%X%0#N1+LI5s>nn>H z_lR0ZQdHVW(m}BYYhy}#IL~$5j0~67`>LJsx}v3QJkAt30k40oW~Wyzbp|C9 zb-i}oCBt$})zsXRzg#nYpB7V=17mN_i2!_t6ZD-z`c+xWDrtjY6)C%%tq%j~Co=^< z=x$P~<Z!e!50XaQ~Wie%W3vXLyoCTq%5shlHt@WG~0gX3M}V3OkA~C zlNM9(AuY3=D{Qu&oVH(V1JsKLM}OyxeG<+k z7fIjIA4rU^Z*tZOhJ(Rq4XR6N=Fl?<<>^+fq@h;nY%6j*x2xoVvWUwMH-5wOw?Cc| zlJiwj5DAZ&YEl*ghaqgZ+CWwHZd^TfxUjwV>4R=< zE}}{Jjn!ZU>@AH$>@`=GjxA?OVq~mAerxWy#qNbIG1#)b4Ys((LE`TdDJsdeY^tbp z8=ds4GM6z?$YiArX|PtU`uSr_eoySd8!>T4y;O(HLlTUor4J)Y)A_p~TyOff>)d0V z#Zs!wGmEEF^0a&tW>jOH0RI3kkWwm<;?pVZM~OrTWe-O}(?^NTQ(&)kxy#g}X4|rf z)+|l#qjH*q(i4=MLeN@U@e=z=JyZ*lG^l;Y7TiGL-3AUu%v0lKDr|W%nt4r1OcANF z1@!~i?R)jU_^3`~jO`Vea$8E0hESH@J1MY*O9)Nv@RG1k_D5W2r&gXR^4+=jt3w@0 zhDN8+XkHTWma9yPXq4yRskn<~Vid$z4!8L!1xhM(-rJ;r06K0h&@-fQQ#Q*oBnDbi zfgVBPELDtJ5K^l{C0)ZYO*5{@) za~wh88;k<&FDN0^TI@MisTBj{d>wmXwt^h!`K3-{Ns!r5vu7T&Q%y9dn`f0B^70g- z-NT04`Su%nVL!z_A=J2mm*|R{Iy;uC$&&m=BNoaO>RGzV%8spM4TXTveDNcS`HLr4 zDlnQ;H=75>!!jE5m!8`}*NIUd>@JU4u<*MU1$Up*Y~SxeYF2 zoKCH_AO_R7Wc`?jm$C%x!IvphMKz6Kq`sGt388-rfD_=~;lB6W1KSAktZQ1|d6&C? z5S!AMHtnAE^fTIGOR=~^DQr69MRgc$tCq4gAgGd)ZlhthrapapJ0*$yMrISuHvD%f za*|th0clZ8<$7?u({Qe&On}VjUE_$@EW$<3@`{UoJZ=sc*W1rWr~KfJ$r$ z0Ce@jKQYI0Q~W~ZwxT%{{{V#~?i?5Uu-Ai`s63Ir$a88iz_u z`78I?JjFc>w4ZkCW!RE$j@iN1rD_`$!@)63Pr>R$fC$bg;>7B;?c3K69foO} z_#Xt>p5opyAr7`Q+ZKRYGRm(by%-+)%9y%JcNyrbSXRU zapjKON%k|$+&0R!TI7t=PO7s4Y*mLXDdetex%hZ&eNn|@QFhE%nsw5ewH8i}yzd*S5Mv*Hk3QdEvVb$zW)F$6ixOqs>G$cIXU8sEiKg( zN?S~!(y+4cFJDiG^t|jw1Zlh>&0kJLgP7x1S!wh2iiGnnt+T8RT5h1Q5!oA(MX^2? z2x{&7>$MY@=~3D#TxMmmmR9?E!c^E&n<)+?5J|S3kC?zi^8LR6q>(lrDDm%Ls?5GD->LTr=r3fkn z>0abprv33GKl{7~)kK8Rck+K$07-9%bO`{Ylger30dCt2elhF?T~KhZKhT-evQpy@ z-CJL!w!+Qqg4}9D5+TvEq{8y~jY&v^%y*-aWGx`1sU(~1b^v0fyt`79COk2g^K&k^ z<(4Ei5uc4d4&?&noYGQ(2d8> z1FA0~{{URE>3kTm!+iTu=Pcz~RWH5 zC422;mdX5a1;aq53U<_laV51SwcL)F>jIf3v6?6hC6enBlRi4uQ~myWT8b~c(38^Rc==ba*a}6txAGI z6t{rUWvfX5sBA#K9q|Zee5o`^iA7B0Ig_gO$9{-hv+qnStw~7=Ai{H&O~IWa*$1m zlmYAOxy7A#BbscSoe{X~`@5B(g5wg9v!t-@u%!hb(Fd+C7rLzSM!5$fRq2(ld0a}m zR!C7VJo3|GKtB<;Oa{iFRqFZ6GIQyV&tVl=KI-b@xUf;Ij|l^&-!8a0$s9C`ORTo; zr=QZ|6?Z1=0PA3vKZm9jt>llVv(0jB^@X;othMM8(2^6*U5QShpe#KwE*mccb<5g< zfbAQERJXp3T|e{Z0EW`EFAJ?Zva4m|8xi#m!y-9L5DO|S*+ zIhNsNeh4(gL?J6&z~Ypbxr*5;w?!Lu^urpN!uH&a7E|P z=A^Pwz0_k^wy=@6T?F~}!S>p#M=J=;%QrdPfxDuuqwtNTF0zvZN1paH&Zqr5I>@C zav_SkUMVIbY@S$F+DSVRacg$K^gDxTmc-xDM@mk1!Q0g&^QW_2A0+UnHfCLQ2~Wa^ z)3KE$XbDMEiNC|tk++~%OfC3kQ68;8u(Fp+MKJ<6qH>krpi*b*bZ?5_-#@AMznz%`4x(fRJuYk3GjYHuMqz$d>ja~UXUn%1Ax49gfZR-i2<%InudICS1E%<-5;D4H|gPiI) zx)n})5~o%Kbw27=gFR|*L2+G1vN{fy^TG08nI1b)!@=g8VYCivZlF>fz1Mr2k`2x9 zGsJqFqdKP;t!=f^qwe--2`A=CFp14xa@q zYg?M

    EmSWQXc-)iwi>SZ%oRRKvDdaV^Geu(55%pb|%+!JAx4%W0s&gAT1VvWX>9 zDY{?O-Ilcig@hDbYU|eBHyBGys=Zc}-l)bpn{}w#l&_CNO{FWa8)^U>927O|<(s5S zT|g!}5cSoeRRr%N!=EqRDnviO>ot1Zcd>vN{vEv8syNo_5K5QHVQ zfol&vi6r;MR%^|bdaWXB4#ZMYALj|rIjB6fG=Ne7w&~KF?``dYy4FXm z?iHl6wJ9db>8OBiFVoawO-{Qh*fU_e2~9#_#JVNw)E2chx&b+LRGOMRgXj4_+ecRU}_9>FPLm)qy;*lkaei+EN#=v8Q2_L z;go5(?^-Hl4F>-J0=~F=N=QOD5g~f5d5}-uf8URn`G1HRqlZ=cl-!|Chc2%w43>cH1^iKK?f6ke`=?v!Cw25rSN=$Q0hPFIv z9wMz>K>%zphT=+)SDq9Ta2teEtI@?{K_ixmeJ#Mq-Xb-WCdB<(cRpts>xn9}+1p~9 zvlnmt#bWwQYb(1Tfz{I6g${9c6@|xhC!@h>)7wA_$aDmY?kIxh}38qX^3-bEI3&#=uCAu!uKUszK}q%QSR0f4;ziW)Ey*R%HMJ2zAEZUns|McQkJPw6lYV5G23&*KQ>hOOLgKQu6aY#>btsZAd=$e{R>}~hq&kygpp&S1 z@9B!UzVN!1aBsBtTXtXstDAfwOqaAC)%RLvDi z1qUJRc zTYOaKifmfFa$^j#(OLoJyQGj5RBk$3{#ZTDGMZyOWrQ-cIA5(rTY&9*It`De*x^&2 z%bB@zLQ*W{tl7Bq+o$1y%0Q0Q?8!A3HOUle#K&Z~^Mazpcbn!bmv0Mq3B7^vlY3vT zEVCNQX~+z`rdI64EG?~+kPzrLBj!HrMQNDLQc8-CHeEpqa3^v{KWlB<26K5X%B4Uh zD@W2vS#8^C(i(HZuTM{0cmhfyKu{*Ox{K^Xa`M~cB(~(MJIV9Jxi{>bh007&t*jwd%6I;y=Zb*M3qI{f}p7QZ-Lv4GkS!iiGij-FHNw=kw zdk-uONupG8Ha6b< zM*c?t@Um)h=N4$t61z0R4@p_mt4@$f+r5pkTR}HRm_#pCiA*~3LQbWPt~z7IGM>dw zxs)L}?u81e%2S^5>KaH#x*L@hn*{v(jkm3#7+l0Lz2B6BE<0m1M!pyY#O)H1FiKvn&0Hu|H+y|L) z#idM%T}?u>5&{gyxn^1(ExMf>-$D-C3u^8#Rb5>YOSuLrYxJ3{wO1OHfVS??Y2u=* zwvu++&!ELY#$pi`?d7{C1)6;V&YaQGKdwMb=qyXmY6<& zHUm!GhuMofpOh(oM^Ge4lb1`0j>&xspB+jzZ95yQYg*?7_HjnAyw_w3uP$UbRS0$E znG|KR)?l2|2y$BqLXoK(pp|sJ?QOQf_J5&8rTaBzXtC7+PNEBnT46lfgbjBZiZAwG z0huQ(LR}{@p>pW~wB{M2I^C4WK}Zc;i=D;6^xJGObL1*}91zV>puGj#Qr^@dx`qCY z?sWDfV$K*2%z(Z|RgCy1fNOJyb4z>y{{WV(F}MLuQ#nmDBgk!TNmIJpHYKejBwSwm zgM2SIGjHhvfd|I{;kWiq5B-{kstr{132__uzL9Jq#@mnjJyYBz%`eoL`Hh!c%hSr% z9#LU_0tg4fcH4dM>T*-kJ(07Tnxu$`R!v&mkY*)i!S2Yp2uom#o%cImz7#o{C|+Ht z=^(99+|#|TbQ^W`!MuF!MV0Kum~!GXNj2FSL)|0Or2k9N(I)>MR-SCE;x3#TdHNmp=;%s6411# zqJVgtAGXH~Y4Ijjcw?EU;;<&vrb9|uk1nX%P^EJcq6aa+kaq8ZtfiKx<>~ol$pR`1 zac3~^CR-2Ksd|%sTGeZf?}qPVy0AAsMPQ`njMLfXsI#Rqqb8M^BQ*wel&;BWH62a^ zXIoX$5|iY2`QuCePngfrIKBDgXW_W=P=q2wDr~5jY3x8hqIc=B#$DoLGh^lnk26xJ zL@zbWMu|=(I?`K7(h{HmvWD2wf0MSSDS7(yCCQfIZ3|119#e_|aKg%NqD`(zwi9%S z27v(S`zBa?!O}&Kq^zNtYV=k!9$;z8l;C~xP+=`NLW{iTED0NRw{Dl;z7C*4(Hbm; zDN9jhmX@`ssY)nP8-|~zPJd1Mx9VF z7>3e`bu2Q6%SFaoaY&XDU9y2n2^PPuJxdZXq%nYqw}ST%+1gy=IwKwq@a^iJVRofD zGp)mJLL|m6H)Ot4%V8xu_>u@DpD+eCB^xWJ=;o53uzLNtSL6t*h^Ww-@iiR)CFhhK zbz5~>if&J>@6#F%n1>Y!7f>eM!2Ve1S{fS(JF^odAb7RI!CZ^(s%hd1g2J@lN`bf| zf4p}X&3UISRcKV|vsEf<@f&TzT9BlUTgTnVx)cq_vU`F2akg{oZY5|^TvA9qzvYBq z6SCU#Wg+-tN|=-`Saran(p03B60`!4v81ZNn*(Fp6xCxYHVC@DlbpjlEZ*HKU%f~Q zEv=Zf9}r%ZfT@}ek~ivmbnAe*ld_~NyDgulUz1k|*0<2x&S_P*YVIP!*H9!5so0UZ zVJ;ljx^sK5w@U&=bl#^hysDWgQ4)(d&Zf%Sc!yJ=aR&jb_>F==x>U~KF zlCqRGtxtl06r*dZ#>2g_y7-#69pDNBi`ME>P1dA~0(=)X`Qzu`1Ndb~;tv>VX{oHBzWA$wX!vO-&LBP)~~YX{RhLw`^#_kzS!R#-Ml* zy;t2~njOsf6z?k`}LpKbm~;OIcu!9c4#dpe@GNHk`7gt$&=W+}GyW z0B_q?CM$~hEr?A-kDI9yTXLK3Pdcd*8$uQu&=e9`1dr#685y4>oV7!zBRNo-eiM-v z^XYy-3Ju3oO9>&8tKC40gpZaV(4|p;$cbF>b4rlpGAbFle?=IrwOK=a(4}c;`>P%u z+W_jYw&404O^$`~(i$zTT6F-~-1fD+@m9reEYxPz(@n3^>e8mv1jbs1`>J^@23l-_ z7Scw=1ob^eEaP1WNZADVRBd8D+;d$n$*wK1T{lIaa$}lT@w)Eiu(ttE)+IVfAlxez zG`6*IXM}|ZL0gbT$5Fd>!6zONPE&5@qlxHm-vjhd9~U@66=FHC0sB@WH@dGcGH5D1GIb+>i+l{`#iw-qM zb{=Pm^?FL`5Xj%9q_xm}n4!;A7iv69%N)_n3#c%muc!d1>G^dy>A9|CY@p_;4^wlt zRebyn)f&{TH}Qf`UY$Yvu~Sy5$xMW;QdSg76s1@j>JQHb zjI|(D;TI)yQ6g|W#}F2z{ZpG>+x7e~4@Qi+KIGGJl9U-Os4S@1c-3%zV+QUa`gKl_ z5UaSE3k9VTdbYmbZYOmmN2#Ic`QDI*RI4U7;UEB^%s05U_rZ2RsYy8sogL>Kcq^Le z2~xR+>LS}7g4hz2^Ru%|1^rlg4Cw_4Bp)5^x$A;FxgA1-4_cJZF|~jiaX_Zds`j^U zPfSnVD0W2Xh`C%utTPEJe^yk2u2PqBLS!#dH#aui+W3RT!0Bv0ig|>V)gMt%2ur;@ zUR#~F@7o;tEy?0*tTf|~p;=X-bt_R_rK;zDw-ww*AX6J{5mu7I7_-Y+P*Exb5_;{4 zC#qBdbz;PLwU}+D9M|UlaED!K#Uw2x1?d2%s24l`04xnuz2-L-Xlg>#xe_Vvr7G${ z)CY0b(-z+F9Hvse-37IK^J-R&wRl!d{KuzGnCC5(JI1`4T0+~jC)`R!!T5(u{{Y6= z8hR-zmY~5Q0FTn@a6eS1#haM2#56q63aqxJnTiddBrvkOo|g3LcE#mFdx%n0y)BR0 z^27*qI=*YD(wu=#ol#~TRk!575-QycBaq@jP*0h**yp-4CSjB=gB_SNtX0zT>`0V+ z!nUfkc?kMFX-s%hON-Z~HXvypM|;}=Sr(lVR|wlKOOV@wbhK$|AzA?-jU`%u{WPCW zo8h@Gk5+FkRbau(_2~}EXX?-?uC|c7Sc9kmfP96+{L@3>q=;22Eb4Ucq#t!Lo~OR* zmW2lFpjrwYQg-ymOBP7;nUy1kX{SbwUR=kdhMRqW7SuIAZ>z9UfFj$2i=5u=I%=|P zR_YSa9ImOvJtms#D9}*px=!~Zr;%0l%N0-eCP zA9e_{kZxq`jNo;pCAzqIz}nWfm~1rXiDW0h2|ZQmh-k1v=Uo8+R*DxhZCiwC19tO*5K`a*cdR0ugh?UGS*gwQvQ&wnKWfZO>#(OPs>9{JFucs z6aldTL#KQ&ou#t_f|;@^CPR5?r@BHR$V=oWmu<-P7#Yg+&v1{JQ#H3@IU>6BmJu>5 z>E^aj*b7Jv^dueqFwD#pmn&Q@szRp3a-~y#8?1)u>^Z5$6pbL2r70cv>Fa~uP?wy! zRwUrNgZfPkBdVgf58Z|*vm0PhD#R6Q54Hk3d>wHUg}epg9$C!L9I52`tY%P!A;&{O zNC)PUcJ=9kE&*lf*(}>_HVJ(Q!&Hn)V6a2ARN|*ltR5*qlP|}>UKTnt? z1Nq=Pfb|*iQ&L?rO5#c}sp;mo)Fn~MR0qslVO}trlr#hQ7Q8t3t`q#au+6!8Ppiq$@w9;Hx;Po~%3ikNZ(D_iLeA;pwi zQqKGK-?jJ03KPeJjQEWEWzX6KpLDLdNGVM5OntW#w-d*5;}t**;a4l7eB->$3n^1*&?Os5+_*1^0gKx7RE-Nrxs8uR%qFeDp z4m|3^7u4!~=|fLZ=W%_njcZ7gnJ84rS$XLyc8fJ_ua@$Pl+utwlcb*5%PT=mO24P{ zTaobf{{XcdXTUdx_d%NvGLE}Jqz7sANBjq&%cIGwzV$)bY|4t#+e-CZZcXmewe2Q2iko{%!Hq(iZ%SkHU*GLy8{&vUg{H*LqEj+1-Qk)kSP$@ku zE)K`7!Suzk$XU(0TuPIT$z{1=#Ws~Ce8Pa=Fgftppu|Q&FyRSC!jd#MDtwfGMhXM;q=&*BxV;XG{@qlml#wrJs$UUSOdr> zQ9vW(0D<1ve<5X^D^ilXBEYN=K=QwpuZ-uw%5`>~n%RpW9C076o`I{b{ zaiK!mb)P69kO*!{j(bjnc{)PFV9ygGjm;fXMx`YIg(#I4zbcJz; zgj)U({Wuf-_V8Q9c4JiNkyx7gps?e~O5O}}3P)uGT{^o9Tw>cOaL$8Q%vnz}K;lkU zZJHC2&%4xCsIEA+%2Wc9;RP4d+gIC-{TRnSoj39>@>qIF?Q7n{sR14Fk<#XFh__1B zdYm@W3Pr8&E!iy8ewZ1lP@x>-Osu_}xPBXlAyO2DW>Kxnp-Bn2Yinx1U%MR% z2J4&$MM<2hEW5;73fjAlE~F1l$PKsvN$YG;Rm0-2!zoB?>Iv7YWc0b|xfq*Vqtog+ zo&`zV_mW|l(u07E#@f6ZR1K_y;<+7h6`EdE6~s!FpR%fv!x^@#iWDK zTK>E5ik$nLGB$UeN16RP%GrH%_LR>emrbfjLc!5*5}H94(oL<^M}C+tqw(j5d4DZN zq^CF0q^dro0=&08q@hbIP`SGAbJtMYwmp#Qpq@&-Zz^vSU@46(m-4-kg^_LL3vbYM zzB%zxo6?aD5ezwzLr8gG_*_=AYZ2FBw%zeq-xs)V2Rw|;A2p6@V5%3mx0faIY*(vN zRHp$Juoktu;*!0_T!ULu)V$ACis)J#N}*64a2+P&QeBV%`R$0xxP` zYEq`N&Ph=!0>lKW{{S)D9wavEc*U2D=!=Tubjc`kG^>T7T)>+sb|&Kk6Zq@H+N@PK zKDU|H651Opr)AjjimXoLs!Hrnnsn{9KdJuETsNiGpw!a5=~I;jr7*&!LVy#?Ci+!% zYFBO4qIMhN8pjP+ih(f;lAG;w*L#tLhZ5^m3LQe4#3}OPrSPDyc9OQiH%J%KMb7>3 z*>RNnx!42e-wBQ|ofV213O^Es{JcoQObdo^0)2}IAteyy${lX06@qhpVS?+bWVDj| zfjU-G)GvORhdw4|iBz2pIkv198TT1c6CO^Yl@yb0ewZi9HF%VY7rs<2I;jbYxR_xN#ZU(b=D zP=iVln>_am2qM_ z>`$%;JdlL7R6CnlMCpp*kEhtc5(vmE0NFS$(mE6~#GR$!I^ya&$r%=&UkPWYI z*Yw0%gxW*7k)@iGPXQgJCB|-ADhj!8VREaU+YdZ*&-JD%?Zj!I(@qw&EeQ(Jh3Zz? zh_Tw+jj#dkFpRVXVL;DW?z=^sQU3r4b(p^CW6G0KlC?N@Hc14F?cW5A)wqP3Jh@8Z zthAWSxcH2UTPRa11Q!Q%h__T0&8w5$$A52r41(9_q~tn3^3K6>5k<& zOe$q5w`4#*35l8w@My2NOoCM<9GtJR?AR9ok2N z&~<6wNk@H>kd!>i(0A-oM_;!I9PdJ;xzdmb1MK`Tw*f0F)YRhORQ$%hItor#LYAZ`sVDPihRV6WOLfBjiXp6Y za|-^EZQ0yZ{FTE>3E=k->S?4?b*C)2bRo2>#ElL#yWEhVr0Uhz)QzyE$RIZ_A|k@& zx`J+hv<@@}3#sZp&AH}MTx_>1E=U9foqCeUJMZKUGv-KDq~sEy1(i@w;tm>ACB>7> z`4xhVv-f(0^npd6QsM4<5TU;+WU4dqVxgoDuTz8#DehIbOjqzDDAn?vZP8z*KS@fX zLGaCNB&))2 z*(-f314LAzdJ?dpd4~QQ+V-~iro9#l2Q#}?icYD;Ff~r9%$RAHBsNqrZwIrRjUl{QWCq<_YMBM?p zxX4i}BV?%F*rFy9)CQE^_r0xxDfEQhc4>YfK(N2>!21z7PNlZv7Y+KGe>^MUnYwt_ z2#}3)m0F(N8Ujp!%aR^KQtH461SFd%pM(-R_S*Yj88l><5Gqq0ujOPSYi^`Qe=tUE z^p!{}vYS%UQfxk7KDgBx%7kWRH6d*3K>;Ns3+^p(zfp{PFM$#pacN>&!gSbcWL+oZ z6^1<@N|*$b1uVq6p|eDUlA5-yAkTetlr9|JU!0#566I{3MBIqee@P+P42d<;n z%Lb8VJoATIi3w6tq6Vwp{vqGD%K}_1iofUuG2stNTwy8`2{ym#?u%Rd-LO{M$5omu zR`%48My;>6?YUschpu~w#5nSm;oDmiAtBKcS{+)6JCG5*fbWTPyr)mDH#S5`Q5_8}zEeK*QtGaubcB;~ZGHL+jqimz zDlW1~Z0HB7dt;lj)akl{N%OWmSWbm{Q_1>nNu^GxDr2pVLIZ8XZ($a1;rCP##TlT+BxKE~}_-r9c)(1^nk&b@y z<@PrDW5JPWUX;jtFlDzGkP!jKS8F2ay|(M|U+~8{96_YI-60>*Dr;+nAiVR1#UFf5 zn`l_J$?w;w!r@XDzNYub_c2x?_ZX1C7m1YBR({EH=@qtQ?uY%BT8x$o;VYHeu6E70u&;8a~}0gNNY>36*Y9~7Zxhjara@1Ps1nRlyFVNvD%~DUqK*zBm&YIP4o+~VqswrBwY}3g| z8+dQ?!hefuTGL8%P%8?1uGaW4)}EyWSqbfIccRB-G6y~^cgk#%Ufc`ceusbMgqRv) znF+oz@(5XxDVVda&MfYA8=k%IkKHp?NYu3tAPK{(JH!;c=O!{4LrHZyi$OjBLb_Od z`s0R>3uGa*tk`KS6ZUn(t|wwqmQrO+NlwbTPwj1wDPm9^6i3R~a8Uvl?NjPmA-B{M zsj#A-OP<(~9keZVCiKT~vX+)UuV6|@xF2Rc#Oz+mQg4$pNh4B6bpemj4r=Z~R6NbF z9lry@bMma7t5Dnxk>0Bv9iH~DqPXL5#QjZSuZl)3TXG(uM)))d+SJq6SS z@9Bpn8M%?CO>G*=Q7P2lK_~jv0ye{Uj*LAgfRxoKwS}TIU1h|S+r+NN?ZJo20wNYw z;c67T?MEkdbCdh<;r3%nlPfd<`UH4y*TzTi!jFa5Mtr0X{{V0YyBg#BMa19Anr zo|d;<6zEfo+Wkh`VM8a{OCZaBI;2r^AQ9nx9;7!aAPYd&HC&{SuNu8QF^i$vTp#fD zSM;W=J?Xc>wIyE7)!rD`VUkz}3D+aBIn&3PYFu4IedAumo(%IQL|#>oED zygSKRb?O9syP7IghhvzkjV`4VX39!P)RsZq6S&1|JYeB7u23Uo?jF@>%8yYF7apqn z+SHXNPK0V9C`yivdgND9ZFJ9Fr`G0 zrTG#%0oV*$WN3yBRTg~)h9zbHpFFK~` zX;K0L4b!?ie>`NxQ5jr7Oz`y_U=q4jg5R9Ahmr|VHrM;kEolvfApuelFXX@Bim6Cg znBm)g_Qj1Y#{$B6X;t>VoGxuK8ZE9RGjh|u?huyWxA%?kVBJAs7gU9iJ0#(EN1nLh z1t6g}wXK3gR$S5XD310`@WqA%C3P7lRO+O%;VLgaqIv;r0OkZCN_}PWNfs$L+XORf zZYg9C;*;9x+X8jT`iUV6Bc=Ix3XbNiq{vhv6K(|qBwF282m=&m1bEU?bzNGzX*>L} zWiqLtl%+2N`y&-z_Th9Wmq5O)>@IPU`A&(0TH$n8U!LFeU3vz@578$G=__MgmwBlU zpxh)jtE%Mm!-lCTa;ORkzT=_lFsE=JNnbTdNxAKb!mwWGDma0nvdI&S#Yu*V1u{!q z=HMwBM1TR*q>;H+YFviwA}9*?HABC9JyIP*SsE3jlmN#^8g!yPPm-Z8Z~v zjL9)pw&|HM=Xt*N5SxgrH!XzR*z5_o*l&!LnEkD@HehX})Uw`Al$#QO=3QWf->$^s zx^K01Z>S{*emy0|P{+EWF{d}k4O+#%S-MJWZKR81NTNZKQsXhAVDQI~oU2O-VeWb( z1eb1}UvCdv-)}EH@M?!qC6uzVQl%e=4xXNvQE;=0)jZ=}c9|vxCKNW}sq~_oO=2m! zRFDPRNH*~kY&MYk7D`oNVPLCRzbh(jU8x%asll#X10A@MP$<-=;l|K={g>-eX ztsi)}zoEy|EYFpq)M(3&>~^G-p-DWw4-}4OX({PM4afv7|+k*Stv~9QO2u_&N*hdg61QN+Ba!qnA&D>;03|W53WZ zfNa`_p%~X0n+3Snc*NVquZ8!S65y-g!fSn!asU~uN7P~jQX#8&Eb z+I*%ZJlJk@fpS3WweRRbI2g*QX?cB;w;MrFQM!$QI*7SGST};kwcOCP!Okt@mI|e~ z*-%g-#Dj6S-;Zdcys!&tE56{Td*f7ahk>*6WANRkW{jaB&il#XaWLKP{20dp}+#;vXbC8O65gdl$DZNLT}fv`>@;g zbfD9!m3sRVVKF%6OL2@2A6s^og~!pTuxTFEQak+}n=1~WEwtYrA_qK!~`oMxU= z>W-@|NgIKysND9pIew3Mej*&{*4qWqV_6glXoaWvsP6`HjOQv@rke&;aZQGk9x-v* zDoEH3Az>*VsQuuvOaAo^}b*T+um zqT8-;Stl}!tLN2|;R#HgfJiqs@8^p+xB6nF+LhoeGD1baXkQa}aYbDE=4g($Lma8a zyOgHoM_>-2-p3Q^R1+^hRq1a!uu~PGeqc$saEspEH~eu)Fk`V=6&*G^Yt89Om*G@3 zTgB9cC;6OzRP?i%sG{T_eNssZxUp>QiDsCJe-Tv=Rryg|vP$o$f{m^%zULj^rKIP~ zwH+=L^C~HAO6C$1be{c21QFFzLAh47N<&J?mFWO#SdXgY{376X#GV5%9+5>`uB@lP zLQ=AjcO7kmJo3t$;eKOzRS7i$Vw9yXx|IZ6q;v@z^&8&-JPRD=X!_n>kc5>4xu;Oo z)2F5eKoW-KROPg~?N+FRtRT;ktP6{ta=gBHaPhV|90}y9C88RPpa~}aC10-nZ-nkw zZ{BBAii&|%PEMsHs1fyq_B(lD-NhK`dx1_NAw?o9D;lm%!-oBL^T7uLDjldLV?G;> zUVNmVDI@pcsqFs%VVZMN2^D6ydzCm* zK!q_9C8U)l#4Us&<%EC;JCucDZxhJPT4+ z5n{18&DVJn!hzJge#%p9R8M^l3j=!|_r%vHFp+y-Z!Pf&`ilpmLH_Nw#G8#&w#tHV zh%Tj}NMGwG5F%31K0+Hpih(_nO0jP?drgo+bzAgF?~hd3W158{>X&_rc0YK<4v4v0 zT1w+zjKpd(TT6B$sIk5myr!6VsK-LeyA*W8aDe2mspmvFb6)bd;LY z*cU~B0kpD?X?Mp70Awjjn&N{f-PZV zYx&?_xv5-8%Y(R7A-DO#jW{tJAJ^!x<4o~?PpbMOQwwez&bF>fklK_M5|tF4_p*Tp z?HJ2ELYr5AFV|a>Dj7}M9Jui#HnpRik#nH|UR&IC#;mB4X>y7kQ!bWQXBswAO^-rB zA9y&;d{1I?SyM3uRHVyjax5AtLuD#?Hwp*<8+0XDdQ1QpIxbQ!vf7aVrt4BvQWdea ziiRvRM>SNm>r&Nc+D_^ud}$tih9qX15rasK?<530C4{!JEq@RseghMDkxh>Zj}=YI zilwFMcx@LgA+Wrq><%A>AIS_4w2G6uiW>c8QE zxRL0zUMb}VX|pLUwvT*Lz176IrCg+oua*_~<6iL#KWc-;Jflha61gpj6enM9E5!md z)^(K>pM@cNpDSGA9Ty={=1`zI?221%xY9!TwFszIz;z065%!F9;)^t7(yNP)HiqPr z9YGhvo(%I4+UY#on+*o$o%J>tdyoNH|FccEAt57$&>ub}0cs5xwth4%5+1m_kw^yx8 zTynhOIZWynLj{x)2p^;qeTQw2--Rz1YO>;ST88sa{d;kOLxq$dJJ~kUKEZ}&QLWY{ z*4~RRHk8Igpf-rjM@rmEl1Q?GNgDy>Y;@8$T>KIchFz)Da_$$s+g!RZyY0qdC0bUUwCU0Y=hvqAsF7W$<<2l?7NS1F z6(BU}a$ICcQoJb}m4bVd+omit&2FVl&$)J^^qO6EO%2rZo`}G0BxzQVjT&^`-L8D_ zB#Bc5-FwWCmUy{CcubJ`q|+RAPc2D9g+j-wKmd$><`$%}nevp!r_?1WH8iBUUMeWM z4#+)^TzIS1DwFdzMXDN$>sygu3sgj6 zr9B~MMZp^bPvot@C_Vr@aB!&Zpzyi}A8H?oJAHy(RnJAhT0 z)`3n%Mb?{n;?g4^p*q5j=JwUG2VsiI5K1uDOdlHAA2kjj)44^Rbx-s0bB#-Pj) zLExH#S#_nZnuipZ!is{8wO>~E$Foh4xv&G47s`Gd>rXcS0K9(;G`KwHCq8C`f&nrf z-?{OtY%22FfX&c|I|&|shYYS2wxsbxFr=FT>(~DP)~sX2H#43&v(+)fx*E^T=$;B~ zWu=q@bFxA1aSFL2hW&0s6k{aQ7)WU{WZ6o2z=5q+u(CDXBfW+FF>=&rCceye%1~4< zsYby7bx}S*T$~7^MK-fCLg|hoEj^_vrks%J`p}Rr<*ZHAZa^Ka>xz0Zk!?3P?yknx z4ye|RmCYqB2+K`{w2|_}Cb>-Qtvjo8Y;}g&Q%WUgMw=ug-ovoPVq-1$w4n++?Y8}G zhJ~v;T{l*tOg8B{dv+KgqN$P+kji~jp=)4m4YtWjoh#^UgqvH-f8mSzGZMYinvGuU zRzNH0v)VD2z0e*~929*ANpGV@U}qI(P0d zJ`-wk+|%MuPNZR4*6CMFvVfakN%{4}q%wr0C=zem5#yv3SoI#AaU+%#pc1r`^R_fK z{FXxAYw>KPHVHt|dK+Q{u->H&HvZ7-_hL(}Eh$%q>HTEyh;m{ir*~|xBi90I9!P@~ zOpZeLSx(1mUmV$y9V-?_!q+DqB~t-dJ6N5~_xrKUic$lX=j#{TTG)xqEEVw^s|uw- zucOM5Ymsg6x^=?i%TZENf==CVb21n(mUO9Pq}Uy>8n_5citoLLY+HwI${K`$Wx<&Z zT~;844?ehoEpgJ~)--F>2a)?RXw*cjS1me-xBv?rR?nrCLsY}bOI+SolInT7t$XOc ztv|JET-&ZTv~`s(bg@a7J)d-Jl?&R|>v4{aRT~fjo3I)Wg53@(q$QHdQsbcj3+=x_ zjz38<)M8U-KphUo*wPy-33gTeQ_nStnPx6rnAm=f)YC2;kl0GuI#d+NAb5v}k#n~H z0AvQ#c|p*iR4r@uBg+F-9O5Xsh3N9zampm1+MHz{6D!gHb-&slh`7bWz{Xk?%x*+S zlg?sGU)8*W(2wFegSHl9u37FY%aa+@;Ioi5a$*$?tll^ zK^8yf6N&s`a7w1aT1D>RxboQI0+Y<*)?DrkxMJR%(TcFGAkv;r^izv)JV^flA64`o zu-craIuPTn-KDG;>r!3YeTsMg0G=|oe~DRglUH1)s!|}f>p=>Z`=u!Q(Q)FkPhV4w zF_@Ao6nQaL+LWGI@FN^|bC1)xe=oI-bR0I6y9cy{+lC-Z^h&C2Uw|%=| z$u>w@6&+@R!))c!6$zsCMWif=O)Y)Sq7bDh4ZN{0iUJ&pl`1n+;l2$*J8Nnyp=tw| zHy|V%{P7kPNO0?UEgth7(%nEU;S86YBp{MVu(|ZT_r%=t|NDm73@{p?!bZqvJ*Et)iU92D3dxAXF#!2@ZR$2{ZYWB23-}NA!P{=s)>-(EX-1j zcyFO7w=Z$vx$n?zZS8_iA=T+{r^Rw>Rd~x`B_WS?X~d{1#P7`(JAV8LQKeGd&NPu3 zillbUGHFAOGL

    + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Atomic Rollbacks + + +

    + + +
      +
    1. Automatic rollbacks
    2. +
    3. Manual rollbacks
    4. +
    5. Rollbacks
    6. +
    7. Alternate rollback techniques
    8. +
    + + +

    + + + Automatic rollbacks + + +

    + + +

    See greenboot for information on automatic rollbacks and how to integrate +without your bootloader.

    +

    + + + Manual rollbacks + + +

    + + +

    Ostree writes bootloader entries that are interpreted by the bootloader. To +manually rollback, for bootloaders such as GRUB and syslinux that have an +interactive UI, it is possible to select a previous boot entry. In the case of +an Android bootloader, a slot switch may be triggererd using an AB switching +tool. This may be useful for testing purposes.

    +

    + + + Rollbacks + + +

    + + +
                            +------------------------------------------------+
    ++------------------+    |                                                |
    +|                  |    |                                                |
    +|                  |    |                                                |
    +|                  |    |      (ostree:0) latest     (multi-user.target) |
    +|                  |    |                                                |
    +| Bootloader       |--->+ root                                           |
    +|                  |    |                                                |
    +|                  |    |      (ostree:1) latest - 1 (multi-user.target) |
    +|                  |    |                                                |
    +|                  |    |                                                |
    ++------------------+    |                                                |
    +                        +------------------------------------------------+
    +
    + +

    Bootloaders have multiple boot entries to choose from after upgrade. On +rollback, the bootloader will boot the “latest - 1” version, rather than the +latest version of the OS.

    +

    + + + Alternate rollback techniques + + +

    + + +

    Below is an alternate technique to traditional AB switching that can be used. +On rollback, an alternative boot target is used, rather than booting as +default.target.

    + +
                            +------------------------------------------------+
    ++------------------+    |                                                |
    +|                  |    |                                                |
    +|                  |    |                                                |
    +|                  |    |      (ostree:0) latest     (multi-user.target) |
    +|                  |    |                                                |
    +| Bootloader       |--->+ root                                           |
    +|                  |    |                                                |
    +|                  |    |      (ostree:1) latest - 1 (rescue.target)     |
    +|                  |    |                                                |
    +|                  |    |                                                |
    ++------------------+    |                                                |
    +                        +------------------------------------------------+
    +
    + +

    In this case, instead of rolling back to an older version, we also boot +into an alternate systemd boot target. Here we will describe how you can put +togther an alternate systemd boot target, using the built-in rescue.target as +an example.

    + +

    Below is a rescue.service file, it essentially executes systemd-sulogin-shell +rescue when this service is activated.

    + +

    rescue.service:

    + +
    #  SPDX-License-Identifier: LGPL-2.1-or-later
    +#
    +#  This file is part of systemd.
    +#
    +#  systemd is free software; you can redistribute it and/or modify it
    +#  under the terms of the GNU Lesser General Public License as published by
    +#  the Free Software Foundation; either version 2.1 of the License, or
    +#  (at your option) any later version.
    +
    +[Unit]
    +Description=Rescue Shell
    +Documentation=man:sulogin(8)
    +DefaultDependencies=no
    +Conflicts=shutdown.target
    +After=sysinit.target plymouth-start.service
    +Before=shutdown.target
    +
    +[Service]
    +Environment=HOME=/root
    +WorkingDirectory=-/root
    +ExecStartPre=-/usr/bin/plymouth --wait quit
    +ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue
    +Type=idle
    +StandardInput=tty-force
    +StandardOutput=inherit
    +StandardError=inherit
    +KillMode=process
    +IgnoreSIGPIPE=no
    +SendSIGHUP=yes
    +
    + +

    Below is a rescue.target file, it is reached once rescue.service is complete.

    + +

    rescue.target:

    + +
    #  SPDX-License-Identifier: LGPL-2.1-or-later
    +#
    +#  This file is part of systemd.
    +#
    +#  systemd is free software; you can redistribute it and/or modify it
    +#  under the terms of the GNU Lesser General Public License as published by
    +#  the Free Software Foundation; either version 2.1 of the License, or
    +#  (at your option) any later version.
    +
    +[Unit]
    +Description=Rescue Mode
    +Documentation=man:systemd.special(7)
    +Requires=sysinit.target rescue.service
    +After=sysinit.target rescue.service
    +AllowIsolate=yes
    +
    + +

    This is a simple bash script, it checks whether ostree admin status -D is +not-default and if it is, it notifies systemd to alternatively boot into +rescue.target.

    + +

    In the happy path, when we have booted the latest version +ostree admin status -D would output default.

    + +

    ostree-rollback-to-rescue:

    + +
    #!/usr/bin/bash
    +
    +set -euo pipefail
    +
    +if [ "$(ostree admin status -D)" = "not-default" ]; then
    +  exec systemctl --no-block isolate rescue.target
    +fi
    +
    + +

    This is a systemd service file that runs ostree-rollback-to-rescue early in the +boot sequence, it is essential that this service is run early to ensure we +don’t execute a full boot sequence, hence options DefaultDependencies=no and +Before= are used.

    + +

    ostree-rollback-to-rescue.service

    + +
    [Unit]
    +Description=OSTree rollback to rescue
    +DefaultDependencies=no
    +OnFailure=emergency.target
    +OnFailureJobMode=replace-irreversibly
    +After=initrd-root-fs.target initrd-fs.target initrd.target boot.mount
    +Before=cryptsetup.target integritysetup.target remote-fs.target slices.target swap.target veritysetup.target
    +
    +[Service]
    +Type=oneshot
    +ExecStart=/usr/sbin/ostree-rollback-to-rescue
    +
    +[Install]
    +WantedBy=sysinit.target
    +
    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/atomic-upgrades/index.html b/atomic-upgrades/index.html new file mode 100644 index 0000000000..c595fca9de --- /dev/null +++ b/atomic-upgrades/index.html @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Atomic Upgrades | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Atomic Upgrades + + +

    + + +
      +
    1. You can turn off the power anytime you want…
    2. +
    3. Simple upgrades via HTTP
    4. +
    5. Upgrades via external tools (e.g. package managers)
    6. +
    7. Assembling a new deployment directory
    8. +
    9. Atomically swapping boot configuration
    10. +
    11. The bootversion
    12. +
    13. The /ostree/boot directory
    14. +
    + + +

    + + + You can turn off the power anytime you want… + + +

    + + +

    OSTree is designed to implement fully atomic and safe upgrades; +more generally, atomic transitions between lists of bootable +deployments. If the system crashes or you pull the power, you +will have either the old system, or the new one.

    +

    + + + Simple upgrades via HTTP + + +

    + + +

    First, the most basic model OSTree supports is one where it replicates +pre-generated filesystem trees from a server over HTTP, tracking +exactly one ref, which is stored in the .origin file for the +deployment. The command ostree admin upgrade +implements this.

    + +

    To begin a simple upgrade, OSTree fetches the contents of the ref from +the remote server. Suppose we’re tracking a ref named +exampleos/buildmain/x86_64-runtime. OSTree fetches the URL +http://example.com/repo/refs/heads/exampleos/buildmain/x86_64-runtime, +which contains a SHA256 checksum. This determines the tree to deploy, +and /etc will be merged from currently booted tree.

    + +

    If we do not have this commit, then we perform a pull process. +At present (without static deltas), this involves quite simply just +fetching each individual object that we do not have, asynchronously. +Put in other words, we only download changed files (zlib-compressed). +Each object has its checksum validated and is stored in /ostree/repo/objects/.

    + +

    Once the pull is complete, we have downloaded all the objects that we need +to perform a deployment.

    +

    + + + Upgrades via external tools (e.g. package managers) + + +

    + + +

    As mentioned in the introduction, OSTree is also designed to allow a +model where filesystem trees are computed on the client. It is +completely agnostic as to how those trees are generated; they could be +computed with traditional packages, packages with post-deployment +scripts on top, or built by developers directly from revision control +locally, etc.

    + +

    At a practical level, most package managers today (dpkg and rpm) +operate “live” on the currently booted filesystem. The way they could +work with OSTree is to, instead, take the list of installed packages in +the currently booted tree, and compute a new filesystem from that. A +later chapter describes in more details how this could work: +Adapting Existing Systems.

    + +

    For the purposes of this section, let’s assume that we have a +newly generated filesystem tree stored in the repo (which shares +storage with the existing booted tree). We can then move on to +checking it back out of the repo into a deployment.

    +

    + + + Assembling a new deployment directory + + +

    + + +

    Given a commit to deploy, OSTree first allocates a directory for +it. This is of the form /boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf. +The $serial is normally 0, but if a +given commit is deployed more than once, it will be incremented. +This is supported because the previous deployment may have +configuration in /etc that we do not want to use or overwrite.

    + +

    Now that we have a deployment directory, a 3-way merge is performed +between the (by default) currently booted deployment’s /etc, its +default configuration, and the new deployment (based on its /usr/etc).

    + +

    How it works is:

    +
      +
    • Files in the currently booted deployment’s /etc which were modified +from the default /usr/etc (of the same deployment) are retained.
    • +
    • Files in the currently booted deployment’s /etc which were not +modified from the default /usr/etc (of the same deployment) are +upgraded to the new defaults from the new deployment’s /usr/etc.
    • +
    + +

    Roughly, this means that as soon as you modify or add a file in /etc, +this file will be propagated forever as is (though there is a +corner-case, where if your modification eventually exactly matches a +future default file, then the file will go back to following future +default updates from that point on).

    + +

    You can use ostree admin config-diff to see the differences between +your booted deployment’s /etc and the OSTree defaults. A command like +diff {/usr,}/etc will additional print line-level differences.

    +

    + + + Atomically swapping boot configuration + + +

    + + +

    At this point, a new deployment directory has been created as a +hardlink farm; the running system is untouched, and the bootloader +configuration is untouched. We want to add this deployment to the +“deployment list”.

    + +

    To support a more general case, OSTree supports atomic transitioning +between arbitrary sets of deployments, with the restriction that the +currently booted deployment must always be in the new set. In the +normal case, we have exactly one deployment, which is the booted one, +and we want to add the new deployment to the list. A more complex +command might allow creating 100 deployments as part of one atomic +transaction, so that one can set up an automated system to bisect +across them.

    +

    + + + The bootversion + + +

    + + +

    OSTree allows swapping between boot configurations by implementing the +“swapped directory pattern” in /boot. This means it is a symbolic +link to one of two directories /ostree/boot.[0|1]. To swap the +contents atomically, if the current version is 0, we create +/ostree/boot.1, populate it with the new contents, then atomically +swap the symbolic link. Finally, the old contents can be garbage +collected at any point.

    +

    + + + The /ostree/boot directory + + +

    + + +

    However, we want to optimize for the case where the set of +kernel/initramfs/devicetree sets is the same between both the old and new +deployment lists. This happens when doing an upgrade that does not +include the kernel; think of a simple translation update. OSTree +optimizes for this case because on some systems /boot may be on a +separate medium such as flash storage not optimized for significant +amounts of write traffic. Related to this, modern OSTree has support +for having /boot be a read-only mount by default - it will +automatically remount read-write just for the portion of time +necessary to update the bootloader configuration.

    + +

    To implement this, OSTree also maintains the directory +/ostree/boot.$bootversion, which is a set +of symbolic links to the deployment directories. The +$bootversion here must match the version of +/boot. However, in order to allow atomic transitions of +this directory, this is also a swapped directory, +so just like /boot, it has a version of 0 or 1 appended.

    + +

    Each bootloader entry has a special ostree= argument which refers to +one of these symbolic links. This is parsed at runtime in the +initramfs.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/authenticated-repos/index.html b/authenticated-repos/index.html new file mode 100644 index 0000000000..c6d4f33411 --- /dev/null +++ b/authenticated-repos/index.html @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Handling access to authenticated remote repositories | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Handling access to authenticated remote repositories + + +

    + + +
      +
    1. Using mutual TLS
    2. +
    3. Using basic authentication
    4. +
    5. Using cookies
    6. +
    + + + +

    There is no default concept of an “ostree server”; ostree expects to talk to a generic webserver, so any tool and technique applicable for generic HTTP can also apply to fetching content via OSTree’s builtin HTTP client.

    +

    + + + Using mutual TLS + + +

    + + +

    The tls-client-cert-path and tls-client-key-path expose the underlying HTTP code for mutual TLS.

    + +

    Each device can be provisioned with a secret key which grants it access to the webserver.

    +

    + + + Using basic authentication + + +

    + + +

    The client supports HTTP basic authentication, but this has well-known management drawbacks.

    +

    + + + Using cookies + + +

    + + +

    Since this pull request ostree supports adding cookies to a remote configuration. This can be used with e.g. Amazon CloudFront.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/bootloaders/index.html b/bootloaders/index.html new file mode 100644 index 0000000000..18bc6bf9bc --- /dev/null +++ b/bootloaders/index.html @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bootloaders | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Bootloaders + + +

    + + +
      +
    1. OSTree and bootloaders
    2. +
    3. OSTree and grub
    4. +
    5. OSTree and aboot
    6. +
    7. GRUB and os-prober
    8. +
    9. Anaconda
    10. +
    11. bootupd
    12. +
    + + +

    + + + OSTree and bootloaders + + +

    + + +

    The intended design of OSTree is that it just writes new files into /boot/loader/entries. There is a legacy GRUB script (shipped on Fedora as ostree-grub2) that is intended only for the cases where the system GRUB does not support the blscfg verb.

    + +

    In the happy path then, the flow of an OS update is just:

    + +
      +
    • ostree writes a new set of files in /boot/loader/entries (during ostree-finalize-staged.service on system shutdown)
    • +
    • On system start, GRUB reads those files
    • +
    + +

    And that’s it.

    +

    + + + OSTree and grub + + +

    + + +

    For historical reasons, OSTree defaults to detecting the bootloader; if some GRUB files are present then OSTree will default to executing grub2-mkconfig.

    +

    + + + OSTree and aboot + + +

    + + +

    The Android bootloader is another bootloader than may be used with ostree. It still uses the files in /boot/loader/entries as metadata, but the boootloader does not read these files. Android bootloaders package their kernel+initramfs+cmdline+dtb in a signed binary blob called an Android Boot Image. This binary blob then is written to either partition boot_a or boot_b depending on which slot is suitable.

    + +

    Android bootloaders by design inject kargs into the cmdline, some patches may be required in the Android bootloader implementation to ensure that the firmware does not switch between system_a and system_b partitions by populating a root= karg, or that a ro karg that is incompatible with ostree is not inserted. Conversly leaving the androidboot.slot_suffix= karg injecting functionality is required but this is commonplace for any Android Bootloader that does AB updates.

    + +

    We have two accompanying scripts that work with this type of environment:

    + +

    aboot-update is used to generate Android Boot Images to be delivered to the client.

    + +

    aboot-deploy reads what the current slot is according to the androidboot.slot_suffix= karg, writes to the alternate boot_a or boot_b slot and sets a symlink either /ostree/root.a or /ostree/root.b so that it is known which userspace directory to boot into based on the androidboot.slot_suffix= karg, on subsequent boots.

    + +
    +-----------------------------+                            +---------------------------------+
    +|                             |    +------------------+    |                                 |
    +|  firmware appends:          |    |                  |    |                                 |
    +|                             +--->+ boot_a partition +--->+                                 |
    +|  androidboot.slot_suffix=_a |    |                  |    |                  /ostree/root.a |
    +|                             |    +------------------+    |                                 |
    +|  or                         |                            | system_a partition              |
    +|                             |    +------------------+    |                                 |
    +|  androidboot.slot_suffix=_b |    |                  |    |                  /ostree/root.b |
    +|                             +--->+ boot_b partition +--->+                                 |
    +|  to cmdline                 |    |                  |    |                                 |
    +|                             |    +------------------+    |                                 |
    ++-----------------------------+                            +---------------------------------+
    +
    +

    + + + GRUB and os-prober + + +

    + + +

    A specific component of GRUB that can significantly impede the reliability of OS updates is the os-prober aspect, which scans all system block devices. If one doesn’t care about dual booting, avoiding this is a good idea.

    +

    + + + Anaconda + + +

    + + +

    Until very recently, the Anaconda project only supported setting up the bootloader (e.g. GRUB) on its own, which requires grub2-mkconfig etc. As of recently, Anaconda now supports bootupd.

    +

    + + + bootupd + + +

    + + +

    As of recently, the bootupd project ships static grub configs and in this case, the sysroot.bootloader should be set to none (except on s390x). +And assuming that the system grub has the blscfg support, which it does on Fedora derivatives per above.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/buildsystem-and-repos/index.html b/buildsystem-and-repos/index.html new file mode 100644 index 0000000000..8b35992a8b --- /dev/null +++ b/buildsystem-and-repos/index.html @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Writing a buildsystem and managing repositories | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Writing a buildsystem and managing repositories + + +

    + + +
      +
    1. Build vs buy
    2. +
    3. Initializing
    4. +
    5. Writing your own OSTree buildsystem
    6. +
    7. Constructing trees from unions
    8. +
    9. Migrating content between repositories
    10. +
    11. More sophisticated repository management
    12. +
    + + + +

    OSTree is not a package system. It does not directly support building +source code. Rather, it is a tool for transporting and managing +content, along with package-system independent aspects like bootloader +management for updates.

    + +

    We’ll assume here that we’re planning to generate commits on a build +server, then have client systems replicate it. Doing client-side +assembly is also possible of course, but this discussion will focus +primarily on server-side concerns.

    +

    + + + Build vs buy + + +

    + + +

    Therefore, you need to either pick an existing tool for writing +content into an OSTree repository, or write your own. An example +tool is rpm-ostree - it +takes as input RPMs, and commits them (currently oriented for +server-side, but aiming to do client-side too).

    +

    + + + Initializing + + +

    + + +

    For this initial discussion, we’re assuming you have a single +archive repository:

    + +
    mkdir repo
    +ostree --repo=repo init --mode=archive
    +
    + +

    You can export this via a static webserver, and configure clients to +pull from it.

    +

    + + + Writing your own OSTree buildsystem + + +

    + + +

    There exist many, many systems that basically follow this pattern:

    + +
    $pkg --installroot=/path/to/tmpdir install foo bar baz
    +$imagesystem commit --root=/path/to/tmpdir
    +
    + +

    For various values of $pkg such as yum, apt-get, etc., and +values of $imagesystem could be simple tarballs, Amazon Machine +Images, ISOs, etc.

    + +

    Now obviously in this document, we’re going to talk about the +situation where $imagesystem is OSTree. The general idea with +OSTree is that wherever you might store a series of tarballs for +applications or OS images, OSTree is likely going to be better. For +example, it supports GPG signatures, binary deltas, writing bootloader +configuration, etc.

    + +

    OSTree does not include a package/component build system simply +because there already exist plenty of good ones - rather, it is +intended to provide an infrastructure layer.

    + +

    The above mentioned rpm-ostree compose tree chooses RPM as the value +of $pkg - so binaries are built as RPMs, then committed as a whole +into an OSTree commit.

    + +

    But let’s discuss building our own. If you’re just experimenting, +it’s quite easy to start with the command line. We’ll assume for this +purpose that you have a build process that outputs a directory tree - +we’ll call this tool $pkginstallroot (which could be yum +--installroot or debootstrap, etc.).

    + +

    Your initial prototype is going to look like:

    + +
    $pkginstallroot /path/to/tmpdir
    +ostree --repo=repo commit -s 'build' -b exampleos/x86_64/standard --tree=dir=/path/to/tmpdir
    +
    + +

    Alternatively, if your build system can generate a tarball, you can +commit that tarball into OSTree. For example, +OpenEmbedded can output a tarball, and +one can commit it via:

    + +
    ostree commit -s 'build' -b exampleos/x86_64/standard --tree=tar=myos.tar
    +
    +

    + + + Constructing trees from unions + + +

    + + +

    The above is a very simplistic model, and you will quickly notice that +it’s slow. This is because OSTree has to re-checksum and recompress +the content each time it’s committed. (Most of the CPU time is spent +in compression which gets thrown away if the content turns out to be +already stored).

    + +

    A more advanced approach is to store components in OSTree itself, then +union them, and recommit them. At this point, we recommend taking a +look at the OSTree API, and choose a programming language supported by +GObject Introspection +to write your buildsystem scripts. Python may be a good choice, or +you could choose custom C code, etc.

    + +

    For the purposes of this tutorial we will use shell script, but it’s +strongly recommended to choose a real programming language for your +build system.

    + +

    Let’s say that your build system produces separate artifacts (whether +those are RPMs, zip files, or whatever). These artifacts should be +the result of make install DESTDIR= or similar. Basically +equivalent to RPMs/debs.

    + +

    Further, in order to make things fast, we will need a separate +bare-user repository in order to perform checkouts quickly via +hardlinks. We’ll then export content into the archive repository +for use by client systems.

    + +
    mkdir build-repo
    +ostree --repo=build-repo init --mode=bare-user
    +
    + +

    You can begin committing those as individual branches:

    + +
    ostree --repo=build-repo commit -b exampleos/x86_64/bash --tree=tar=bash-4.2-bin.tar.gz
    +ostree --repo=build-repo commit -b exampleos/x86_64/systemd --tree=tar=systemd-224-bin.tar.gz
    +
    + +

    Set things up so that whenever a package changes, you redo the +commit with the new package version - conceptually, the branch +tracks the individual package versions over time, and defaults to +“latest”. This isn’t required - one could also include the version in +the branch name, and have metadata outside to determine “latest” (or +the desired version).

    + +

    Now, to construct our final tree:

    + +
    rm -rf exampleos-build
    +for package in bash systemd; do
    +  ostree --repo=build-repo checkout -U --union exampleos/x86_64/${package} exampleos-build
    +done
    +# Set up a "rofiles-fuse" mount point; this ensures that any processes
    +# we run for post-processing of the tree don't corrupt the hardlinks.
    +mkdir -p mnt
    +rofiles-fuse exampleos-build mnt
    +# Now run global "triggers", generate cache files:
    +ldconfig -r mnt
    +  (Insert other programs here)
    +fusermount -u mnt
    +ostree --repo=build-repo commit -b exampleos/x86_64/standard --link-checkout-speedup exampleos-build
    +
    + +

    There are a number of interesting things going on here. The major +architectural change is that we’re using --link-checkout-speedup. +This is a way to tell OSTree that our checkout is made via hardlinks, +and to scan the repository in order to build up a reverse (device, +inode) -> checksum mapping.

    + +

    In order for this mapping to be accurate, we needed the rofiles-fuse +to ensure that any changed files had new inodes (and hence a new +checksum).

    +

    + + + Migrating content between repositories + + +

    + + +

    Now that we have content in our build-repo repository (in +bare-user mode), we need to move the exampleos/x86_64/standard +branch content into the repository just named repo (in archive +mode) for export, which will involve zlib compression of new objects. +We likely want to generate static deltas after that as well.

    + +

    Let’s copy the content:

    + +
    ostree --repo=repo pull-local build-repo exampleos/x86_64/standard
    +
    + +

    Clients can now incrementally download new objects - however, this +would also be a good time to generate a delta from the previous +commit.

    + +
    ostree --repo=repo static-delta generate exampleos/x86_64/standard
    +
    +

    + + + More sophisticated repository management + + +

    + + +

    Next, see Repository Management for the +next steps in managing content in OSTree repositories.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/composefs/index.html b/composefs/index.html new file mode 100644 index 0000000000..6661bfd92d --- /dev/null +++ b/composefs/index.html @@ -0,0 +1,420 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Using composefs with OSTree | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Using composefs with OSTree + + +

    + + +
      +
    1. composefs
        +
      1. Enabling composefs (unsigned)
      2. +
      3. composefs configuration
      4. +
      5. Injecting composefs digests
      6. +
      7. Signatures
      8. +
      +
    2. +
    3. Requirements
    4. +
    5. Status
    6. +
    7. Compatiblity
    8. +
    9. Comparison with other approaches
    10. +
    11. Further references
    12. +
    + + +

    + + + composefs + + +

    + + +

    The composefs project is a new +hybrid Linux stacking filesystem that provides many benefits when +used for bootable host systems, such as a strong story for integrity.

    + +

    At the current time, integration of composefs and ostree is experimental. +This issue tracks the latest status.

    +

    + + + Enabling composefs (unsigned) + + +

    + + +

    When building a disk image or to transition an existing system, run:

    + +
    ostree config --repo=/ostree/repo set ex-integrity.composefs true
    +
    + +

    This will ensure that any future deployments (e.g. created by ostree admin upgrade) +have a .ostree.cfs file in the deployment directory which is a mountable +composefs metadata file, with a “backing store” directory that is +shared with the current /ostree/repo/objects.

    +

    + + + composefs configuration + + +

    + + +

    The ostree-prepare-root binary will look for ostree/prepare-root.conf in /etc and +/usr/lib in the initramfs. Using that configuration file you can enable composefs, +and specify an Ed25519 public key to validate the booted commit.

    + +

    See the manpage for ostree-prepare-root for details of how to configure it.

    +

    + + + Injecting composefs digests + + +

    + + +

    When generating an OSTree commit, there is a CLI switch --generate-composefs-metadata +and a corresponding C API ostree_repo_commit_add_composefs_metadata. This will +inject the composefs digest as metadata into the ostree commit under a metadata +key ostree.composefs.v0. Because an OSTree commit can be signed, this allows +covering the composefs fsverity digest with a signature.

    +

    + + + Signatures + + +

    + + +

    If a commit is signed with an Ed25519 private key (see ostree +--sign), and composefs.keyfile is specified in prepare-root.conf, +then the initrd will find the commit being booted in the system repo +and validate its signature against the public key. It will then ensure +that the composefs digest being booted has an fs-verity digest +matching the one in the commit. This allows a fully trusted read-only +/usr.

    + +

    The exact usage of the signature is up to the user, but a common way +to use it with transient keys. This is done like this:

    +
      +
    • Generate a new keypair before each build
    • +
    • Embed the public key in the initrd that is part of the commit.
    • +
    • Ensure the initrd has a prepare-root.conf with [composefs] enabled=signed, and either use keypath or inject /etc/ostree/initramfs-root-binding.key; for more see man ostree-prepare-root
    • +
    • After committing, run ostree --sign with the private key.
    • +
    • Throw away the private key.
    • +
    + +

    When a transient key is used this way, that ties the initrd with the +userspace part from the commit. This means each initrd can only boot +the very same userspace it was made for. For example, if an older +version of the OS has a security flaw, you can’t boot a new fixed +(signed) initrd and have it boot the older userspace with the flaw.

    +

    + + + Requirements + + +

    + + +

    The current default composefs integration in ostree does not have any +requirements from the underlying kernel and filesystem other than +having the following kernel options set:

    + +
      +
    • CONFIG_OVERLAY_FS
    • +
    • CONFIG_BLK_DEV_LOOP
    • +
    • CONFIG_EROFS_FS
    • +
    + +

    At the current time, there are no additional userspace runtime requirements.

    +

    + + + Status + + +

    + + +

    IMPORTANT The integration with composefs is experimental and subject to change. Please +try it and report issues but do not deploy to production systems yet.

    +

    + + + Compatiblity + + +

    + + +

    One issue that ostree users transitioning to composefs may hit is that it is no +longer possible to add new toplevel directories via the chattr -i / && mkdir /somedir && chattr -i +trick. A bit more on this in the following issues:

    + + + +

    However, users who were doing things like this probably want to enable the +root.transient option; see man ostree-prepare-root which will allow +this (but also change other behaviors too).

    +

    + + + Comparison with other approaches + + +

    + + +

    There is also support for using IMA with ostree. In short, composefs +provides much stronger and more efficient integrity:

    + +
      +
    • composefs validates an entire filesystem tree, not just individual files
    • +
    • composefs makes files actually read-only, whereas IMA does not by default
    • +
    • composefs uses fs-verity which does on-demand verification (IMA by default does a full readahead of every file accessed, though IMA can also use fs-verity as a backend)
    • +
    +

    + + + Further references + + +

    + + +
      +
    • https://github.com/containers/composefs
    • +
    • https://www.kernel.org/doc/html/next/filesystems/fsverity.html
    • +
    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/contributing-tutorial/index.html b/contributing-tutorial/index.html new file mode 100644 index 0000000000..f2df9437c1 --- /dev/null +++ b/contributing-tutorial/index.html @@ -0,0 +1,850 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +OSTree Contributing Tutorial | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + OSTree Contributing Tutorial + + +

    + + +

    The following guide is about OSTree forking, building, adding a command, testing the command, and submitting the change.

    + +
      +
    1. Getting Started
    2. +
    3. Building OSTree
        +
      1. Install Build Dependencies
      2. +
      3. OSTree Build Commands
          +
        1. Notes
        2. +
        3. Tip
        4. +
        +
      4. +
      +
    4. +
    5. Testing a Build
        +
      1. Testing in a Container
      2. +
      3. Testing in a Virtual Machine
      4. +
      +
    6. +
    7. Tutorial: Adding a basic builtin command to ostree
        +
      1. Modifying OSTree
      2. +
      3. Adding a new API function to libostree
      4. +
      5. OSTree Tests
      6. +
      7. Submitting a Patch
      8. +
      9. Returning Workflow
      10. +
      +
    8. +
    + + +

    + + + Getting Started + + +

    + + +

    Fork https://github.com/ostreedev/ostree, then run the following commands.

    + +
    $ git clone https://github.com/<username>/ostree && cd ostree
    +$ git remote add upstream https://github.com/ostreedev/ostree
    +$ git checkout main
    +$ git fetch upstream && git branch --set-upstream-to=upstream/main main
    +
    +

    Make a branch from main for your patch.

    + +
    $ git checkout -b <name-of-branch>
    +$ git branch --set-upstream-to=upstream/main <name-of-branch>
    +
    +

    + + + Building OSTree + + +

    + +

    + + + Install Build Dependencies + + +

    + + +

    Execute one of the following group commands as superuser depending on your machine’s package manager.

    + +

    For Fedora:

    + +
    $ dnf install @buildsys-build dnf-plugins-core && \
    +dnf builddep ostree
    +
    + +

    For CentOS:

    + +
    $ yum install yum-utils dnf-plugins-core && \
    +yum-builddep ostree
    +
    + +

    For Debian based distros:

    + +
    $ apt-get update && \
    +apt-get install build-essential && \
    +apt-get build-dep ostree
    +
    + +

    build.sh will have a list of packages needed to build ostree.

    +

    + + + OSTree Build Commands + + +

    + + +

    These are the basic commands to build OSTree. Depending on the OS that OSTree will be built for, the flags or options for ./autogen.sh and ./configure will vary.

    + +

    See ostree-build.sh in this tutorial below for specific commands to building OSTree for Fedora 28 and Fedora 28 Atomic Host.

    + +
    # optional: autogen.sh will run this if necessary
    +git submodule update --init
    +
    +env NOCONFIGURE=1 ./autogen.sh
    +
    +# run ./configure if makefile does not exist
    +./configure
    +
    +make
    +make install DESTDIR=/path/to/install/binary
    +
    +

    + + + Notes + + +

    + + +

    Running git submodule update --init is optional since autogen.sh will check to see if one of the submodule files for example from libglnx/ or from bsdiff/ exists.

    + +

    Additionally, autogen.sh will check to see if the environment variable NOCONFIGURE is set. To run ./configure manually, run autogen in a modified environment as such, env NOCONFIGURE=1 ./autogen.sh.

    + +

    Otherwise, leave NOCONFIGURE empty and autogen.sh will run ./configure as part of the autogen.sh command when it executes.

    + +

    For more information on --prefix see Variables for Installation Directories.

    + +

    make install will generate files for /bin and /lib. If DESTDIR is unspecified then OSTree will be installed in the default directory i.e. /usr/local/bin and its static libraries in /usr/local/lib. Note that the /usr/local portion of the path can be changed using the --prefix option for ./configure.

    + +

    See this GNU guide on DESTDIR Staged Installs for more information.

    +

    + + + Tip + + +

    + + +

    Make allows parallel execution of recipes. Use make -j<N> to speed up the build. <N> is typically $((2 * $(nproc))) for optimal performance, where nproc is the number of processing units (CPU cores) available.

    + +

    See page 106 of the GNU Make Manual for more information about the --jobs or -j option.

    +

    + + + Testing a Build + + +

    + + +

    It is best practice to build software (definitely including ostree) in a container or virtual machine first.

    +

    + + + Testing in a Container + + +

    + + +

    There are a variety of container engines available and many distributions have pre-packaged versions of e.g. Podman and Docker.

    + +

    If you choose to use Docker upstream, you may want to follow this post-installation guide for Docker. This will allow you to run Docker as a non-root user on a Linux based host machine.

    + +

    You will need to have pushed a remote git branch $REMOTE_BRANCH (see ostree-git.sh below) in order to pull your changes into a container.

    + +

    The example below uses Docker to manage containers. Save the contents of this Dockerfile somewhere on your machine:

    + +
    # this pulls the fedora 28 image
    +FROM registry.fedoraproject.org/fedora:28
    +
    +# install ostree dependencies
    +RUN dnf update -y && \
    +    dnf -y install @buildsys-build dnf-plugins-core  && \
    +    dnf -y builddep ostree  && \
    +    dnf clean all
    +
    +# clone ostree and update main branch
    +COPY ostree-git.sh /
    +RUN ../ostree-git.sh
    +
    +# builds ostree + any additional commands
    +COPY ostree-build.sh /
    +
    +# entry into the container will start at this directory
    +WORKDIR /ostree
    +
    +# run the following as `/bin/sh -c`
    +# or enter the container to execute ./ostree-build.sh
    +RUN ../ostree-build.sh
    +
    +
    + +

    Save the following bash scripts in the same directory as the Dockerfile. Then change the mode bit of these files so that they are executable, by running chmod +x ostree-git.sh ostree-build.sh

    + +
    #!/bin/bash
    +
    +# ostree-git.sh
    +# Clone ostree and update main branch
    +
    +set -euo pipefail
    +
    +# Set $USERNAME to your GitHub username here.
    +USERNAME=""
    +
    +# clone your fork of the OSTree repo, this will be in the "/" directory
    +git clone https://github.com/$USERNAME/ostree.git
    +cd ostree
    +
    +# Add upstream as remote and update main branch
    +git checkout main  
    +git remote add upstream https://github.com/ostreedev/ostree.git
    +git pull --rebase upstream main
    +
    + +
    #!/bin/bash
    +
    +# ostree-build.sh
    +# Build and test OSTree
    +
    +set -euo pipefail
    +
    +# $REMOTE_BRANCH is the name of the remote branch in your
    +# repository that contains changes (e.g. my-patch).
    +REMOTE_BRANCH=""
    +
    +# fetch updates from origin
    +# origin url should be your forked ostree repository
    +git fetch origin
    +
    +# go to branch with changes
    +# if this branch already exists then checkout that branch
    +exit_code="$(git checkout --track origin/$REMOTE_BRANCH; echo $?)"
    +if [[ "$exit_code" == 1 ]]
    +then
    +    echo "This branch:" $REMOTE_BRANCH "is not a remote branch."
    +    exit
    +fi
    +
    +# make sure branch with changes is up-to-date
    +git pull origin $REMOTE_BRANCH
    +
    +# build OSTree commands for Fedora 28 and Fedora 28 Atomic Host
    +./autogen.sh --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc
    +./configure --prefix=/usr
    +make -j$((2 * $(nproc)))
    +make install
    +
    +# any additional commands go here
    +
    + +

    Build the container

    + +

    Run docker build in the same directory of the Dockerfile like so:

    + +
    $ docker build -t ostree-fedora-test .
    +
    + +

    When this build is done, the -t option tags the image as ostree-fedora-test.

    + +

    Note: Do not forget the dot . at the end of the above command which specifies the location of the Dockerfile.

    + +

    You will see ostree-fedora-test listed when running docker images:

    + +
    REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
    +ostree-fedora-test                         latest              817c04cc3656        1 day ago          978MB
    +
    + +

    Entering the Container

    + +

    To start the ostree-fedora-test container, run:

    + +
    $ docker run -it --rm --entrypoint /bin/sh --name ostree-testing ostree-fedora-test
    +
    + +

    Note:

    + +

    --rm option tells Docker to automatically clean up the container and remove the file system when the container exits. Otherwise remove it manually by running docker rm <container name>.

    + +

    The state of the container will not be saved when the shell prompt exits. Best practice is modify the Dockerfile to modify the image.

    + +

    Testing in a Container Workflow

    + +
      +
    1. Edit the changes to OSTree on your local machine.
    2. +
    3. git add to stage the changed files, git commit and then git push origin <local-branch>:<remote-branch>.
    4. +
    5. +

      Testing on a new container vs. Testing on an existing container:

      + +

      If the ostree-testing container was newly built right after your changes have been committed, then the container’s build of ostree should contain your changes.

      + +

      Else: Within the ostree-testing container, run ../ostree-build.sh in the ostree directory. This will pull in changes from your branch and create a new ostree build.

      +
    6. +
    7. +

      make install will install OSTree in the default location i.e. /usr/..in a Fedora 28 container.

      +
    8. +
    9. Test ostree.
    10. +
    +

    + + + Testing in a Virtual Machine + + +

    + + +

    To create a Fedora 28 Atomic Host Vagrant VM, run the following commands:

    + +
    $ mkdir atomic && cd atomic
    +$ vagrant init fedora/28-atomic-host && vagrant up
    +
    + +

    An option is to use rsync to transfer ostree files to a Vagrant VM.

    + +

    To find the IP address of a Vagrant VM, run vagrant ssh-config in the same directory as the Vagrantfile.

    + +

    Steps to rsync files to test an ostree build:

    + +
      +
    1. +

      Copy the contents of your public ssh key on your host machine e.g. id_rsa.pub to /home/vagrant/.ssh/authorized_keys on the VM.

      +
    2. +
    3. +

      Run sudo su, followed by ssh localhost then press Ctrl+c to exit from the decision prompt. This will create the .ssh directory with the right permissions.

      +
    4. +
    5. +

      Using Vagrant as the user, run sudo cp ~/.ssh/authorized_keys /root/.ssh/. So that user root has the the same login credentials.

      +
    6. +
    7. +

      To override the Read-only file system warning, run sudo ostree admin unlock.

      +
    8. +
    9. +

      <ostree-install-dir> will serve as the local install location for ostree and the path to this directory should be absolute when specified in DESTDIR.

      +
    10. +
    11. +

      Set rsync to sync changes in /etc and /usr from <ostree-install-dir>/ on the host to the VM:

      + +
       $ rsync -av <ostree-install-dir>/etc/ root@<ip-address>:/etc
      + $ rsync -av <ostree-install-dir>/usr/ root@<ip-address>:/usr
      +
      + +

      Using option -n will execute the commands as a trial, which is helpful to list the files that will be synced.

      +
    12. +
    13. +

      Run the commands in step 6 each time a new ostree build is executed to update the change. Running ls -lt in the directory where the changed file is expected, is a simple way to check when a particular file was last modified. Proceed to the test changes ostree with the most recent changes.

      +
    14. +
    +

    + + + Tutorial: Adding a basic builtin command to ostree + + +

    + +

    + + + Modifying OSTree + + +

    + + +

    This will add a command which prints Hello OSTree! when ostree hello-ostree is entered.

    + +
      +
    1. +

      Create a file in src/ostree named ot-builtin-hello-ostree.c. Code that lives in here belongs to OSTree, and uses functionality from libostree.

      +
    2. +
    3. +

      Add the following to ot-builtin-hello-ostree.c:

      + +
       #include "config.h"
      +
      + #include "ot-main.h"
      + #include "ot-builtins.h"
      + #include "ostree.h"
      + #include "otutil.h"
      +
      + // Structure for options such as ostree hello-ostree --option.
      + static GOptionEntry options[] = {
      +   { NULL },
      + };
      +
      + gboolean
      + ostree_builtin_hello_ostree (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
      + {
      +   g_autoptr(OstreeRepo) repo = NULL;
      +
      +   // Creates new command context, ready to be parsed.
      +   // Input to g_option_context_new shows when running ostree <command> --help
      +   g_autoptr(GOptionContext) context = g_option_context_new ("");
      +
      +   // Parses the command context according to the ostree CLI.
      +   if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error))
      +     return FALSE;
      +
      +   g_print("Hello OSTree!\n");
      +
      +   return TRUE;
      + }
      +
      + +

      This defines the functionality for hello-ostree. Now we have to make sure the CLI can refer to the execution function, and that autotools knows to build this file. + Note: libostree codebase supports C99 features.

      +
    4. +
    5. +

      Add the following in src/ostree/main.c:

      + +
       { "hello-ostree",               // The name of the command
      +   OSTREE_BUILTIN_FLAG_NO_REPO,  // Flag not to require the `--repo` argument, see "ot-main.h"
      +   ostree_builtin_hello_ostree,  // Execution function for the command
      +   "Print hello message" },      // Short description to appear when `ostree hello-ostree --help` is entered
      +
      +
    6. +
    7. +

      Add a macro for the function declaration of ostree_builtin_hello_ostree, in ot-builtins.h:

      + +
       BUILTINPROTO(hello_ostree);
      +
      + +

      This makes the function definition visible to the CLI.

      +
    8. +
    9. +

      Configure automake to include ot-builtin-hello-ostree.c in the build, by adding an entry in Makefile-ostree.am under ostree_SOURCES:

      + +
       src/ostree/ot-builtin-hello-ostree.c \
      +
      +
    10. +
    11. +

      Rebuild ostree:

      + +
       $ make && make install DESTDIR=/path/to/install/the/content
      +
      +
    12. +
    13. +

      Execute the new ostree binary, from where you installed it:

      + +
       $ ostree hello-ostree
      + Hello OSTree!
      +
      +
    14. +
    +

    + + + Adding a new API function to libostree + + +

    + + +

    This will add a new API function ostree_kernel_args_foo() in src/libostree/ostree-kernel-args.c.

    + +
      +
    1. +

      Add the following to src/libostree/ostree-kernel-args.h: + _OSTREE_PUBLIC + gboolean ostree_kernel_args_foo (const char *arg, GCancellable *cancellable, GError **error);

      +
    2. +
    3. +

      Add the following to ostree-kernel-args.c: + /** + * ostree_kernel_args_foo: + * @arg: Description of the arg + * + * Description of the function + * + * Since: $NEWVERSION //The new libostree version, for example 2022.5 + **/ + gboolean + ostree_kernel_args_foo (const char *arg, GCancellable *cancellable, GError **error) + { + //Add code here + }

      +
    4. +
    5. +

      Add the following to src/libostree/libostree-devel.sym: + LIBOSTREE_$NEWVERSION { // The new libostree version + global: + ostree_kernel_args_foo; // Function name + } LIBOSTREE_$LASTSTABLE; // The last stable libostree version

      +
    6. +
    7. +

      Add the following to Makefile-libostree.am: + if BUILDOPT_IS_DEVEL_BUILD + symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym + endif

      +
    8. +
    9. +

      Add function name ostree_kernel_args_foo to apidoc/ostree-sections.txt under <FILE>ostree-kernel-args</FILE>.

      +
    10. +
    11. +

      Call function ostree_kernel_args_foo() in your code.

      +
    12. +
    +

    + + + OSTree Tests + + +

    + + +

    Tests for OSTree are done by shell scripting, by running OSTree commands and examining output. These steps will go through adding a test for hello-ostree.

    + +
      +
    1. +

      Create a file in tests called test-hello-ostree.sh.

      +
    2. +
    3. +

      Add the following to test-hello-ostree.sh:

      + +
       set -euo pipefail           # Ensure the test will not silently fail
      +
      + . $(dirname $0)/libtest.sh  # Make libtest.sh functions available
      +
      + echo "1..1"                 # Declare which test is being run out of how many
      +
      + pushd ${test_tmpdir}
      +
      + ${CMD_PREFIX} ostree hello-ostree > hello-output.txt
      + assert_file_has_content hello-output.txt "Hello OSTree!"
      +
      + popd
      +
      + echo "ok hello ostree"      # Indicate test success
      +
      + +

      Many tests require a fake repository setting up (as most OSTree commands require --repo to be specified). See test-pull-depth.sh for an example of this setup.

      +
    4. +
    5. +

      Configure automake to include test-hello-ostree.sh in the build, by adding an entry in Makefile-tests.am under _installed_or_uninstalled_test_scripts:

      + +
       tests/test-hello-ostree.sh \
      +
      +
    6. +
    7. +

      Make sure test-hello-ostree.sh has executable permissions!

      + +
       $ chmod +x tests/test-hello-ostree.sh
      +
      +
    8. +
    9. +

      Run the test:

      + +
       $ make check TESTS="tests/test-hello-ostree.sh"
      +
      + +

      Multiple tests can be specified: make check TESTS="test1 test2 ...". To run all tests, use make check.

      + +

      Hopefully, the test passes! The following will be printed:

      + +
       PASS: tests/test-hello-ostree.sh 1 hello ostree
      + ============================================================================
      + Testsuite summary for libostree 2018.8
      + ============================================================================
      + # TOTAL: 1
      + # PASS:  1
      + # SKIP:  0
      + # XFAIL: 0
      + # FAIL:  0
      + # XPASS: 0
      + # ERROR: 0
      + ============================================================================
      +
      +
    10. +
    +

    + + + Submitting a Patch + + +

    + + +

    After you have committed your changes and tested, you are ready to submit your patch!

    + +

    You should make sure your commits are placed on top of the latest changes from upstream/main:

    + +
    $ git pull --rebase upstream main
    +
    + +

    To submit your patch, open a pull request from your forked repository. Most often, you’ll be merging into ostree:main from <username>:<branch name>.

    + +

    If some of your changes are complete and you would like feedback, you may also open a pull request that has WIP (Work In Progress) in the title.

    + +

    Before a pull request is considered merge ready, your commit messages should fall within the specified guideline. See Commit message style.

    + +

    See CONTRIBUTING.md for information on squashing commits, and alternative options to submit patches.

    +

    + + + Returning Workflow + + +

    + + +

    When returning to work on a patch, it is recommended to update your fork with the latest changes in the upstream main branch.

    + +

    If creating a new branch:

    + +
    $ git checkout main
    +$ git pull upstream main
    +$ git checkout -b <name-of-patch>
    +
    + +

    If continuing on a branch already created:

    + +
    $ git checkout <name-of-patch>
    +$ git pull --rebase upstream main
    +
    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/deployment/index.html b/deployment/index.html new file mode 100644 index 0000000000..36b24d39fd --- /dev/null +++ b/deployment/index.html @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deployments | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Deployments + + +

    + + +
      +
    1. Overview
        +
      1. “stateroot” (AKA “osname”): Group of deployments that share /var
      2. +
      3. Contents of a deployment
      4. +
      5. Staged deployments
      6. +
      7. The system /boot
      8. +
      +
    2. +
    + + +

    + + + Overview + + +

    + + +

    Built on top of the OSTree versioning filesystem core is a layer +that knows how to deploy, parallel install, and manage Unix-like +operating systems (accessible via ostree admin). The core content of these operating systems +are treated as read-only, but they transparently share storage.

    + +

    A deployment is physically located at a path of the form +/ostree/deploy/$stateroot/deploy/$checksum. +OSTree is designed to boot directly into exactly one deployment +at a time; each deployment is intended to be a target for +chroot() or equivalent.

    +

    + + + “stateroot” (AKA “osname”): Group of deployments that share /var + + +

    + + +

    Each deployment is grouped in exactly one “stateroot” (also known as an “osname”); +the former term is preferred.

    + +

    From above, you can see that a stateroot is physically represented in the +/ostree/deploy/$stateroot directory. For example, OSTree can allow parallel +installing Debian in /ostree/deploy/debian and Red Hat Enterprise Linux in +/ostree/deploy/rhel (subject to operating system support, present released +versions of these operating systems may not support this).

    + +

    Each stateroot has exactly one copy of the traditional Unix /var, +stored physically in /ostree/deploy/$stateroot/var. OSTree provides +support tools for systemd to create a Linux bind mount that ensures +the booted deployment sees the shared copy of /var.

    + +

    OSTree does not touch the contents of /var. Operating system +components such as daemon services are required to create any +directories they require there at runtime +(e.g. /var/cache/$daemonname), and to manage upgrading data formats +inside those directories.

    +

    + + + Contents of a deployment + + +

    + + +

    A deployment begins with a specific commit (represented as a +SHA256 hash) in the OSTree repository in /ostree/repo. This commit refers +to a filesystem tree that represents the underlying basis of a +deployment. For short, we will call this the “tree”, to +distinguish it from the concept of a deployment.

    + +

    First, the tree must include a kernel (and optionally an initramfs). The +current standard locations for these are /usr/lib/modules/$kver/vmlinuz and +/usr/lib/modules/$kver/initramfs.img. The “boot checksum” will be computed +automatically. This follows the current Fedora kernel layout, and is +the current recommended path. However, older versions of libostree don’t +support this; you may need to also put kernels in the previous (legacy) +paths, which are vmlinuz(-.*)?-$checksum in either /boot or /usr/lib/ostree-boot. +The checksum should be a SHA256 hash of the kernel contents; it must be +pre-computed before storing the kernel in the repository. Optionally, +the directory can also contain an initramfs, stored as +initramfs(-.*)?-$checksum and/or a device tree, stored as +devicetree(-.*)?-$checksum. If an initramfs or devicetree exist, +the checksum must include all of the kernel, initramfs and devicetree contents. +OSTree will use this to determine which kernels are shared. The rationale for +this is to avoid computing checksums on the client by default.

    + +

    The deployment should not have a traditional UNIX /etc; instead, it +should include /usr/etc. This is the “default configuration”. When +OSTree creates a deployment, it performs a 3-way merge using the +old default configuration, the active system’s /etc, and the new +default configuration. In the final filesystem tree for a deployment +then, /etc is a regular writable directory.

    + +

    Besides the exceptions of /var and /etc then, the rest of the +contents of the tree are checked out as hard links into the +repository. It’s strongly recommended that operating systems ship all +of their content in /usr, but this is not a hard requirement.

    + +

    Finally, a deployment may have a .origin file, stored next to its +directory. This file tells ostree admin upgrade how to upgrade it. +At the moment, OSTree only supports upgrading a single refspec. +However, in the future OSTree may support a syntax for composing +layers of trees, for example.

    +

    + + + Staged deployments + + +

    + + +

    As mentioned above, when OSTree creates a new deployment, a 3-way merge is done +to update its /etc. Depending on the nature of the system, this can cause an +issue: if a user or program modifies the booted /etc after the pending +deployment is created but before rebooting, those modifications will be lost. +OSTree does not do a second /etc merge on reboot.

    + +

    To counter this, OSTree supports staged deployments. In this flow, deployments +are created using e.g. ostree admin upgrade --stage on the CLI. The new +deployment is still created when the command is invoked, but the 3-way /etc +merge is delayed until the system is rebooted or shut down. Additionally, +updating the bootloader is also delayed. This is done by the +ostree-finalize-staged.service systemd unit.

    + +

    The main disadvantage of this approach is that rebooting can take longer and the +failure mode can be confusing (the machine will reboot into the same +deployment). In systems where the workload is well-understood and not subject to +the /etc issue above, it may be better to not stage deployments.

    +

    + + + The system /boot + + +

    + + +

    While OSTree parallel installs deployments cleanly inside the +/ostree directory, ultimately it has to control the system’s /boot +directory. The way this works is via the +Boot Loader Specification, +which is a standard for bootloader-independent drop-in configuration +files.

    + +

    When a tree is deployed, it will have a configuration file generated +of the form +/boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf. This +configuration file will include a special ostree= kernel argument +that allows the initramfs to find (and chroot() into) the specified +deployment.

    + +

    At present, not all bootloaders implement the BootLoaderSpec, so +OSTree contains code for some of these to regenerate native config +files (such as /boot/syslinux/syslinux.conf) based on the entries.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/formats/index.html b/formats/index.html new file mode 100644 index 0000000000..35f610eccc --- /dev/null +++ b/formats/index.html @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +OSTree data formats | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + OSTree data formats + + +

    + + +
      +
    1. On the topic of “smart servers”
    2. +
    3. The archive format
    4. +
    5. archive efficiency
    6. +
    7. Aside: bare formats
    8. +
    9. Static deltas
    10. +
    11. Static delta repository layout
    12. +
    13. Static delta internal structure
        +
      1. The delta superblock
      2. +
      +
    14. +
    15. A delta part
    16. +
    17. Fallback objects
    18. +
    + + +

    + + + On the topic of “smart servers” + + +

    + + +

    One really crucial difference between OSTree and git is that git has a +“smart server”. Even when fetching over https://, it isn’t just a +static webserver, but one that e.g. dynamically computes and +compresses pack files for each client.

    + +

    In contrast, the author of OSTree feels that for operating system +updates, many deployments will want to use simple static webservers, +the same target most package systems were designed to use. The +primary advantages are security and compute efficiency. Services like +Amazon S3 and CDNs are a canonical target, as well as a stock static +nginx server.

    +

    + + + The archive format + + +

    + + +

    In the repo section, the concept of objects was introduced, +where file/content objects are checksummed and managed individually. +(Unlike a package system, which operates on compressed aggregates).

    + +

    The archive format simply gzip-compresses each content object. +Metadata objects are stored uncompressed. This means that it’s easy +to serve via static HTTP. Note: the repo config file still uses the +historical term archive-z2 as mode. But this essentially indicates +the modern archive format.

    + +

    When you commit new content, you will see new .filez files appearing +in objects/.

    +

    + + + archive efficiency + + +

    + + +

    The advantages of archive:

    + +
      +
    • It’s easy to understand and implement
    • +
    • Can be served directly over plain HTTP by a static webserver
    • +
    • Clients can download/unpack updates incrementally
    • +
    • Space efficient on the server
    • +
    + +

    The biggest disadvantage of this format is that for a client to +perform an update, one HTTP request per changed file is required. In +some scenarios, this actually isn’t bad at all, particularly with +techniques to reduce HTTP overhead, such as +HTTP/2.

    + +

    In order to make this format work well, you should design your content +such that large data that changes infrequently (e.g. graphic images) +are stored separately from small frequently changing data (application +code).

    + +

    Other disadvantages of archive:

    + +
      +
    • It’s quite bad when clients are performing an initial pull (without HTTP/2),
    • +
    • One doesn’t know the total size (compressed or uncompressed) of content +before downloading everything
    • +
    +

    + + + Aside: bare formats + + +

    + + +

    The most common operation is to pull from a remote archive repository +into a local one. This latter is not compressed on disk. In other +words, pulling to a local repository is similar to unpacking (but not +installing) the content of an RPM/deb package.

    + +

    The bare repository format is the simplest one. In this mode regular files +are directly stored to disk, and all metadata (e.g. uid/gid and xattrs) is +reflected to the filesystem. +It allows further direct access to content and metadata, but it may require +elevated privileges when writing objects to the repository.

    + +

    The bare-user format is a bit special in that the uid/gid and xattrs +from the content are ignored. This is primarily useful if you want to +have the same OSTree-managed content that can be run on a host system +or an unprivileged container.

    + +

    Similarly, the bare-split-xattrs format is a special mode where xattrs +are stored as separate repository objects, and not directly reflected to +the filesystem. +This is primarily useful when transporting xattrs through lossy environments +(e.g. tar streams and containerized environments). It also allows carrying +security-sensitive xattrs (e.g. SELinux labels) out-of-band without involving +OS filesystem logic.

    +

    + + + Static deltas + + +

    + + +

    OSTree itself was originally focused on a continuous delivery model, where +client systems are expected to update regularly. However, many OS vendors +would like to supply content that’s updated e.g. once a month or less often.

    + +

    For this model, we can do a lot better to support batched updates than +a basic archive repo. However, we still want to preserve the +model of “static webserver only”. Given this, OSTree has gained the +concept of a “static delta”.

    + +

    These deltas are targeted to be a delta between two specific commit +objects, including “bsdiff” and “rsync-style” deltas within a content +object. Static deltas also support from NULL, where the client can +more efficiently download a commit object from scratch - this is +mostly useful when using OSTree for containers, rather than OS images. +For OS images, one tends to download an installer ISO or qcow2 image +which is a single file that contains the tree data already.

    + +

    Effectively, we’re spending server-side storage (and one-time compute +cost), and gaining efficiency in client network bandwidth.

    +

    + + + Static delta repository layout + + +

    + + +

    Since static deltas may not exist, the client first needs to attempt +to locate one. Suppose a client wants to retrieve commit ${new} +while currently running ${current}.

    + +

    In order to save space, these two commits are “modified base64” - the +/ character is replaced with _.

    + +

    Like the commit objects, a “prefix directory” is used to make +management easier for filesystem tools.

    + +

    A delta is named $(mbase64 $from)-$(mbase64 $to), for example +GpTyZaVut2jXFPWnO4LJiKEdRTvOw_mFUCtIKW1NIX0-L8f+VVDkEBKNc1Ncd+mDUrSVR4EyybQGCkuKtkDnTwk, +which in SHA256 format is +1a94f265a56eb768d714f5a73b82c988a11d453bcec3f985502b48296d4d217d-2fc7fe5550e410128d73535c77e98352b495478132c9b4060a4b8ab640e74f09.

    + +

    Finally, the actual content can be found in +deltas/$fromprefix/$fromsuffix-$to.

    +

    + + + Static delta internal structure + + +

    + + +

    A delta is itself a directory. Inside, there is a file called +superblock which contains metadata. The rest of the files will be +integers bearing packs of content.

    + +

    The file format of static deltas should be currently considered an +OSTree implementation detail. Obviously, nothing stops one from +writing code which is compatible with OSTree today. However, we would +like the flexibility to expand and change things, and having multiple +codebases makes that more problematic. Please contact the authors +with any requests.

    + +

    That said, one critical thing to understand about the design is that +delta payloads are a bit more like “restricted programs” than they are +raw data. There’s a “compilation” phase which generates output that +the client executes.

    + +

    This “updates as code” model allows for multiple content generation +strategies. The design of this was inspired by that of Chromium: +ChromiumOS Autoupdate.

    +

    + + + The delta superblock + + +

    + + +

    The superblock contains:

    + +
      +
    • arbitrary metadata
    • +
    • delta generation timestamp
    • +
    • the new commit object
    • +
    • An array of recursive deltas to apply
    • +
    • An array of per-part metadata, including total object sizes (compressed and uncompressed),
    • +
    • An array of fallback objects
    • +
    + +

    Let’s define a delta part, then return to discuss details:

    +

    + + + A delta part + + +

    + + +

    A delta part is a combination of a raw blob of data, plus a very +restricted bytecode that operates on it. Say for example two files +happen to share a common section. It’s possible for the delta +compilation to include that section once in the delta data blob, then +generate instructions to write out that blob twice when generating +both objects.

    + +

    Realistically though, it’s very common for most of a delta to just be +“stream of new objects” - if one considers it, it doesn’t make sense +to have too much duplication inside operating system content at this +level.

    + +

    So then, what’s more interesting is that OSTree static deltas support +a per-file delta algorithm called +bsdiff that most notably works +well on executable code.

    + +

    The current delta compiler scans for files with matching basenames in +each commit that have a similar size, and attempts a bsdiff between +them. (It would make sense later to have a build system provide a +hint for this - for example, files within a same package).

    + +

    A generated bsdiff is included in the payload blob, and applying it is +an instruction.

    +

    + + + Fallback objects + + +

    + + +

    It’s possible for there to be large-ish files which might be resistant +to bsdiff. A good example is that it’s common for operating systems +to use an “initramfs”, which is itself a compressed filesystem. This +“internal compression” defeats bsdiff analysis.

    + +

    For these types of objects, the delta superblock contains an array of +“fallback objects”. These objects aren’t included in the delta +parts - the client simply fetches them from the underlying .filez +object.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/ima/index.html b/ima/index.html new file mode 100644 index 0000000000..28619e0395 --- /dev/null +++ b/ima/index.html @@ -0,0 +1,397 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Using Linux IMA with OSTree | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + Using Linux IMA with OSTree + + +

    + + +
      +
    1. Linux IMA
    2. +
    3. IMA signatures and OSTree checksum
    4. +
    5. Signing
        +
      1. Generating a key
      2. +
      3. Signing a commit
      4. +
      5. Applying a policy
      6. +
      7. Linux EVM
      8. +
      +
    6. +
    7. Further references
    8. +
    + + +

    + + + Linux IMA + + +

    + + +

    The Linux Integrity Measurement Architecture +provides a mechanism to cryptographically sign the digest of a regular +file, and policies can be applied to e.g. require that code executed +by the root user have a valid signed digest.

    + +

    The alignment between Linux IMA and ostree is quite strong. OSTree +provides a content-addressable object store, where files are intended +to be immutable. This is implemented with a basic read-only bind mount.

    + +

    While IMA does not actually prevent mutating files, any changed (or unsigned) +files would (depending on policy) not be readable or executable.

    +

    + + + IMA signatures and OSTree checksum + + +

    + + +

    Mechanically, IMA signatures appear as a security.ima extended attribute +on the file. This is a signed digest of just the file content (and not +any metadata)

    + +

    OSTree’s checksums in contrast include not just the file content, but also +metadata such as uid, gid and mode and extended attributes;

    + +

    Together, this means that adding an IMA signature to a file in the OSTree +model appears as a new object (with a new digest). A nice property is that +this enables the transactional addition (or removal) of IMA signatures. +However, adding IMA signatures to files that were previously unsigned +also today duplicates disk space.

    +

    + + + Signing + + +

    + + +

    To apply IMA signatures to an OSTree commit, there is an ima-sign +command implemented currently in the ostree-rs-ext +project.

    +

    + + + Generating a key + + +

    + + +

    There is documentation for this in man evmctl and the upstream IMA +page; we will not replicate it here.

    +

    + + + Signing a commit + + +

    + + +

    ima-sign requires 4 things:

    + +
      +
    • An OSTree repository (could be any mode; archive or e.g. bare-user)
    • +
    • A ref or commit digest (e.g. exampleos/x86_64/stable)
    • +
    • A digest algorithm (usually sha256, but you may use e.g. sha512 as well)
    • +
    • An RSA private key
    • +
    + +

    You can then add IMA signatures to all regular files in the commit:

    + +
    $ ostree-ext-cli ima-sign --repo=repo exampleos/x86_64/stable sha256 /path/to/key.pem
    +
    + +

    Many different choices are possible for the signing model. For example, +your build system could store individual components/packages in their own +ostree refs, and sign them at build time. This would avoid re-signing +all binaries when creating production builds. Although note you +still likely want to sign generated artifacts from unioning individual +components, such as a dpkg/rpm database or equivalent and cache files +such as the ldconfig and GTK+ icon caches, etc.

    +

    + + + Applying a policy + + +

    + + +

    Signing a commit by itself will have little to no effect. You will also +need to include in your builds an IMA policy.

    +

    + + + Linux EVM + + +

    + + +

    The EVM subsystem builds on IMA, and adds another signature which +covers most file data, such as the uid, gid and mode and selected +security-relevant extended attributes.

    + +

    This is quite close to the ostree native checksum - the ordering +of the fields is different so the checksums are physically different, but +logically they are very close.

    + +

    However, the focus of the EVM design seems to mostly +be on machine-specific signatures with keys stored in a TPM. +Note that doing this on a per-machine basis would add a new +security.evm extended attribute, and crucially that +changes the ostree digest - so from ostree’s perspective, +these objects will appear corrupt.

    + +

    In the future, ostree may learn to ignore the presence of security.evm +extended attributes.

    + +

    There is also some support for “portable” EVM signatures - by +default, EVM signatures also include the inode number and generation +which are inherently machine-specific.

    + +

    A future ostree enhancement may instead also focus on supporting +signing commits with these “portable” EVM signatures in addition to IMA.

    +

    + + + Further references + + +

    + + +
      +
    • https://sourceforge.net/p/linux-ima/wiki/Home/
    • +
    • https://en.opensuse.org/SDB:Ima_evm
    • +
    • https://wiki.gentoo.org/wiki/Integrity_Measurement_Architecture
    • +
    • https://fedoraproject.org/wiki/Changes/Signed_RPM_Contents
    • +
    • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/managing_monitoring_and_updating_the_kernel/enhancing-security-with-the-kernel-integrity-subsystem_managing-monitoring-and-updating-the-kernel
    • +
    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000000..3fd9c7744a --- /dev/null +++ b/index.html @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +libostree | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + +
    + +

    + + + libostree + + +

    + + +
      +
    1. Operating systems and distributions using OSTree
    2. +
    3. Distribution build tools
    4. +
    5. Projects linking to libostree
    6. +
    7. Language bindings
    8. +
    9. Building
    10. +
    11. API Reference
    12. +
    13. Manual Pages
    14. +
    15. Contact and discussion forums
    16. +
    17. Contributing
    18. +
    19. Licensing
    20. +
    + + + +

    This project is now known as “libostree”, though it is still appropriate to use +the previous name: “OSTree” (or “ostree”). The focus is on projects which use +libostree’s shared library, rather than users directly invoking the command line +tools (except for build systems). However, in most of the rest of the +documentation, we will use the term “OSTree”, since it’s slightly shorter, and +changing all documentation at once is impractical. We expect to transition to +the new name over time.

    + +

    As implied above, libostree is both a shared library and suite of command line +tools that combines a “git-like” model for committing and downloading bootable +filesystem trees, along with a layer for deploying them and managing the +bootloader configuration.

    + +

    The core OSTree model is like git in that it checksums individual files and has +a content-addressed-object store. It’s unlike git in that it “checks out” the +files via hardlinks, and they thus need to be immutable to prevent corruption. +Therefore, another way to think of OSTree is that it’s just a more polished +version of +Linux VServer hardlinks.

    + +

    Features:

    + +
      +
    • Transactional upgrades and rollback for the system
    • +
    • Replicating content incrementally over HTTP via GPG signatures and “pinned TLS” support
    • +
    • Support for parallel installing more than just 2 bootable roots
    • +
    • Binary history on the server side (and client)
    • +
    • Introspectable shared library API for build and deployment systems
    • +
    • Flexible support for multiple branches and repositories, supporting +projects like Flatpak which +use libostree for applications, rather than hosts.
    • +
    +

    + + + Operating systems and distributions using OSTree + + +

    + + +

    Apertis uses libostree for their host system as +well as Flatpak. See update documentation and +apertis-update-manager

    + +

    Endless OS uses libostree for their host system as +well as Flatpak. See +their eos-updater +and deb-ostree-builder +projects.

    + +

    For Debian/apt, see also https://github.com/stb-tester/apt2ostree +and the LWN article Merkle trees and build systems.

    + +

    Fedora derivatives use rpm-ostree (noted below); there are 4 variants using OSTree:

    + + + +

    Red Hat Enterprise Linux CoreOS is a derivative of Fedora CoreOS, used in OpenShift 4. +The machine-config-operator +manages upgrades. RHEL CoreOS is also the successor to RHEL Atomic Host, which +uses rpm-ostree as well.

    + +

    Red Hat In-Vehicle Operating System (RHIVOS) is a derivative of CentOS Automotive Stream Distribution that uses OSTree, it’s closest Fedora derivative is Fedora IoT although it was created as it’s own distribution.

    + +

    GNOME Continuous is +where OSTree was born - as a high performance continuous delivery/testing +system for GNOME.

    + +

    GNOME OS is a testing OS that uses libostree for +their host system as well as Flatpak.

    + +

    Liri OS has the option to install +their distribution using ostree.

    + +

    Torizon OS +is a Linux distribution for embedded systems that updates via OSTree images +delivered via Uptane and +aktualizr.

    +

    + + + Distribution build tools + + +

    + + +

    meta-updater is +a layer available for OpenEmbedded +systems.

    + +

    QtOTA is Qt’s over-the-air update framework +which uses libostree.

    + +

    The BuildStream build and +integration tool supports importing and exporting from libostree repos.

    + +

    fedora-iot/otto is a tool that helps +ship ostree commits inside Docker/OCI containers and run a webserver +to serve the commits.

    + +

    Fedora coreos-assembler is +the build tool used to generate Fedora CoreOS derivatives.

    + +

    debos is a tool-chain for simplifying the +process of building a Debian-based OS image.

    + +

    gardenlinux/ostree-image-builder +is a sample for building Debian-based OS images. +It is not production ready but it might be useful to get started.

    +

    + + + Projects linking to libostree + + +

    + + +

    rpm-ostree is used by the +Fedora-derived operating systems listed above. It is a full hybrid +image/package system. By default it uses libostree to atomically replicate a base OS +(all dependency resolution is done on the server), but it supports “package layering”, where +additional RPMs can be layered on top of the base. This brings a “best of both worlds”” +model for image and package systems.

    + +

    eos-updater is a daemon that implements updates +on EndlessOS.

    + +

    Flatpak uses libostree for desktop +application containers. Unlike most of the other systems here, Flatpak does not +use the “libostree host system” aspects (e.g. bootloader management), just the +“git-like hardlink dedup”. For example, Flatpak supports a per-user OSTree +repository.

    + +

    aktualizr is an +Uptane-conformant software update client library +intended for use in automotive and other security-sensitive embedded devices. +It uses OSTree to manage the OS of the host device by default.

    +

    + + + Language bindings + + +

    + + +

    libostree is accessible via GObject Introspection; +any language which has implemented the GI binding model should work. +For example, Both pygobject +and gjs are known to work +and further are actually used in libostree’s test suite today.

    + +

    Some bindings take the approach of using GI as a lower level and +write higher level manual bindings on top; this is more common +for statically compiled languages. Here’s a list of such bindings:

    + + +

    + + + Building + + +

    + + +

    Releases are available as GPG signed git tags, and most recent +versions support extended validation using +git-evtag.

    + +

    However, in order to build from a git clone, you must update the +submodules. If you’re packaging OSTree and want a tarball, I +recommend using a “recursive git archive” script. There are several +available online; +this code +in OSTree is an example.

    + +

    Once you have a git clone or recursive archive, building is the +same as almost every autotools project:

    + +
    git submodule update --init
    +env NOCONFIGURE=1 ./autogen.sh
    +./configure --prefix=...
    +make
    +make install DESTDIR=/path/to/dest
    +
    +

    + + + API Reference + + +

    + + +

    The libostree API documentation is available in Reference.

    +

    + + + Manual Pages + + +

    + + +

    The ostree manual pages are available in Manual.

    +

    + + + Contact and discussion forums + + +

    + + +

    There is also an #ostree channel on Libera.Chat as +well as enabled Github discussions.

    +

    + + + Contributing + + +

    + + +

    See Contributing.

    +

    + + + Licensing + + +

    + + +

    The licensing for the code of libostree can be canonically found in the individual files; +and the overall status in the COPYING +file in the source. Currently, that’s LGPLv2+. This also covers the man pages and API docs.

    + +

    The license for the manual documentation in the doc/ directory is: +SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later) +This is intended to allow use by Wikipedia and other projects.

    + +

    In general, files should have a SPDX-License-Identifier and that is canonical.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/introduction/index.html b/introduction/index.html new file mode 100644 index 0000000000..50951060be --- /dev/null +++ b/introduction/index.html @@ -0,0 +1,441 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +OSTree Overview | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + + + +
    +
    + + + + + + + + + + + +
    + +
    + + + + +
    + +

    + + + OSTree Overview + + +

    + + +
      +
    1. Introduction
    2. +
    3. Hello World example
    4. +
    5. Comparison with “package managers”
    6. +
    7. Comparison with block/image replication
    8. +
    9. Atomic transitions between parallel-installable read-only filesystem trees
    10. +
    + + +

    + + + Introduction + + +

    + + +

    OSTree is an upgrade system for Linux-based operating systems that +performs atomic upgrades of complete filesystem trees. It is +not a package system; rather, it is intended to complement them. +A primary model is composing packages on a server, and then +replicating them to clients.

    + +

    The underlying architecture might be summarized as “git for +operating system binaries”. It operates in userspace, and will +work on top of any Linux filesystem. At its core is a git-like +content-addressed object store with branches (or “refs”) to track +meaningful filesystem trees within the store. Similarly, one can +check out or commit to these branches.

    + +

    Layered on top of that is bootloader configuration, management of +/etc, and other functions to perform an upgrade beyond just +replicating files.

    + +

    You can use OSTree standalone in the pure replication model, +but another approach is to add a package manager on top, +thus creating a hybrid tree/package system.

    +

    + + + Hello World example + + +

    + + +

    OSTree is mostly used as a library, but a quick tour of using its +CLI tools can give a general idea of how it works at its most +basic level.

    + +

    You can create a new OSTree repository using init:

    + +
    $ ostree --repo=repo init
    +
    + +

    This will create a new repo directory containing your +repository. Feel free to inspect it.

    + +

    Now, let’s prepare some data to add to the repo:

    + +
    $ mkdir tree
    +$ echo "Hello world!" > tree/hello.txt
    +
    + +

    We can now import our tree/ directory using the commit +command:

    + +
    $ ostree --repo=repo commit --branch=foo tree/
    +
    + +

    This will create a new branch foo pointing to the full tree +imported from tree/. In fact, we could now delete tree/ if we +wanted to.

    + +

    To check that we indeed now have a foo branch, you can use the +refs command:

    + +
    $ ostree --repo=repo refs
    +foo
    +
    + +

    We can also inspect the filesystem tree using the ls and cat +commands:

    + +
    $ ostree --repo=repo ls foo
    +d00775 1000 1000      0 /
    +-00664 1000 1000     13 /hello.txt
    +$ ostree --repo=repo cat foo /hello.txt
    +Hello world!
    +
    + +

    And finally, we can check out our tree from the repository:

    + +
    $ ostree --repo=repo checkout foo tree-checkout/
    +$ cat tree-checkout/hello.txt
    +Hello world!
    +
    +

    + + + Comparison with “package managers” + + +

    + + +

    Because OSTree is designed for deploying core operating +systems, a comparison with traditional “package managers” such +as dpkg and rpm is illustrative. Packages are traditionally +composed of partial filesystem trees with metadata and scripts +attached, and these are dynamically assembled on the client +machine, after a process of dependency resolution.

    + +

    In contrast, OSTree only supports recording and deploying +complete (bootable) filesystem trees. It +has no built-in knowledge of how a given filesystem tree was +generated or the origin of individual files, or dependencies, +descriptions of individual components. Put another way, OSTree +only handles delivery and deployment; you will likely still want +to include inside each tree metadata about the individual +components that went into the tree. For example, a system +administrator may want to know what version of OpenSSL was +included in your tree, so you should support the equivalent of +rpm -q or dpkg -L.

    + +

    The OSTree core emphasizes replicating read-only OS trees via +HTTP, and where the OS includes (if desired) an entirely +separate mechanism to install applications, stored in /var if they’re system global, or +/home for per-user +application installation. An example application mechanism is +http://docker.io/

    + +

    However, it is entirely possible to use OSTree underneath a +package system, where the contents of /usr are computed on the client. +For example, when installing a package, rather than changing the +currently running filesystem, the package manager could assemble +a new filesystem tree that layers the new packages on top of a +base tree, record it in the local OSTree repository, and then +set it up for the next boot. To support this model, OSTree +provides an (introspectable) C shared library.

    +

    + + + Comparison with block/image replication + + +

    + + +

    OSTree shares some similarity with “dumb” replication and +stateless deployments, such as the model common in “cloud” +deployments where nodes are booted from an (effectively) +readonly disk, and user data is kept on a different volumes. +The advantage of “dumb” replication, shared by both OSTree and +the cloud model, is that it’s reliable +and predictable.

    + +

    But unlike many default image-based deployments, OSTree supports +exactly two persistent writable directories that are preserved across +upgrades: /etc and /var.

    + +

    Because OSTree operates at the Unix filesystem layer, it works +on top of any filesystem or block storage layout; it’s possible +to replicate a given filesystem tree from an OSTree repository +into plain ext4, BTRFS, XFS, or in general any Unix-compatible +filesystem that supports hard links. Note: OSTree will +transparently take advantage of some BTRFS features if deployed +on it.

    + +

    OSTree is orthogonal to virtualization mechanisms like AMIs and qcow2 +images, though it’s most useful though if you plan to update stateful +VMs in-place, rather than generating new images.

    + +

    In practice, users of “bare metal” configurations will find the OSTree +model most useful.

    +

    + + + Atomic transitions between parallel-installable read-only filesystem trees + + +

    + + +

    Another deeply fundamental difference between both package +managers and image-based replication is that OSTree is +designed to parallel-install multiple versions of multiple +independent operating systems. OSTree +relies on a new toplevel ostree directory; it can in fact +parallel install inside an existing OS or distribution +occupying the physical / root.

    + +

    On each client machine, there is an OSTree repository stored +in /ostree/repo, and a set of “deployments” stored in /ostree/deploy/$STATEROOT/$CHECKSUM. +Each deployment is primarily composed of a set of hardlinks +into the repository. This means each version is deduplicated; +an upgrade process only costs disk space proportional to the +new files, plus some constant overhead.

    + +

    The model OSTree emphasizes is that the OS read-only content +is kept in the classic Unix /usr; it comes with code to +create a Linux read-only bind mount to prevent inadvertent +corruption. There is exactly one /var writable directory shared +between each deployment for a given OS. The OSTree core code +does not touch content in this directory; it is up to the code +in each operating system for how to manage and upgrade state.

    + +

    Finally, each deployment has its own writable copy of the +configuration store /etc. On upgrade, OSTree will +perform a basic 3-way diff, and apply any local changes to the +new copy, while leaving the old untouched.

    + + + + + + + +
    + + + + +
    +
    + + + +
    + + +
    + + + + + diff --git a/man/index.html b/man/index.html new file mode 100644 index 0000000000..87c511e4d5 --- /dev/null +++ b/man/index.html @@ -0,0 +1 @@ +OSTree Manual diff --git a/man/ostree-admin-cleanup.html b/man/ostree-admin-cleanup.html new file mode 100644 index 0000000000..b8d8c80677 --- /dev/null +++ b/man/ostree-admin-cleanup.html @@ -0,0 +1,3 @@ +ostree admin cleanup

    Name

    ostree-admin-cleanup — Delete untagged deployments and repository objects

    Synopsis

    ostree admin cleanup

    Description

    + OSTree sysroot cleans up other bootversions and old deployments. If/when a pull or deployment is interrupted, a partially written state may remain on disk. This command cleans up any such partial states. +

    Example

    $ ostree admin cleanup

    diff --git a/man/ostree-admin-config-diff.html b/man/ostree-admin-config-diff.html new file mode 100644 index 0000000000..1fff9e5277 --- /dev/null +++ b/man/ostree-admin-config-diff.html @@ -0,0 +1,8 @@ +ostree admin config-diff

    Name

    ostree-admin-config-diff — Diff current /etc configuration versus default

    Synopsis

    ostree admin config-diff [OPTIONS...]

    Description

    + Prints the differences between the current /etc directory and the default configuration in /usr/etc. Newly added files (present in /etc but not in /usr/etc) will be prefixed with 'A'. Modified files will be prefixed with 'M', and deleted files with 'D'. +

    Options

    --os="STATEROOT"

    + Use a different operating system stateroot than the current one. +

    Example

    $ ostree admin config-diff

    +        M   shadow
    +        A   example.txt
    +	
    diff --git a/man/ostree-admin-deploy.html b/man/ostree-admin-deploy.html new file mode 100644 index 0000000000..d7d661f670 --- /dev/null +++ b/man/ostree-admin-deploy.html @@ -0,0 +1,42 @@ +ostree admin deploy

    Name

    ostree-admin-deploy — Checkout a revision as the new default deployment

    Synopsis

    ostree admin deploy [OPTIONS...] {REFSPEC}

    Description

    + Takes a commit or revision REFSPEC, and queues the new deployment as default upon reboot. +

    Options

    --stateroot="STATEROOT"

    + Use a different operating system stateroot than the current one. +

    --os="STATEROOT"

    + Alias for --stateroot. +

    --origin-file="FILENAME"

    + Use FILENAME as the origin, which is where OSTree will look for updated versions of the tree. +

    --retain

    + Do not delete previous deployment. +

    --retain-pending

    + Do not delete pending deployments. +

    --retain-rollback

    + Do not delete rollback deployments. +

    --not-as-default

    + Append rather than prepend new deployment. +

    --lock-finalization

    + The deployment will not be "finalized" by default on shutdown; to later + queue it, use ostree admin lock-finalization --unlock. +

    --karg-proc-cmdline

    + Import current /proc/cmdline. +

    --karg="NAME=VALUE"

    + Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the same name. +

    --karg-append="NAME=VALUE"

    + Append kernel argument; useful with e.g. console= that can be used multiple times. +

    --karg-delete="NAME=VALUE"

    + Delete kernel argument if exists, can be used multiple times. +

    Example

    $ ostree admin status

    +        * gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +          gnome-ostree ce19c41036cc45e49b0cecf6b157523c2105c4de1ce3.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +

    $ ostree admin deploy gnome-ostree/buildmain/x86_64-runtime

    +        ostadmin: Creating deployment /ostree/deploy/gnome-ostree/deploy/7e382b11d213a402a5313e61cbc69dfd5ab93cb07.1
    +        ostadmin: Processing /etc: 3 modified, 0 removed, 29 added
    +        Transaction complete: bootconfig swap: no deployment count change: 0)
    +

    $ ostree admin status

    +          gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.1
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +        * gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +
    diff --git a/man/ostree-admin-init-fs.html b/man/ostree-admin-init-fs.html new file mode 100644 index 0000000000..5535fac10e --- /dev/null +++ b/man/ostree-admin-init-fs.html @@ -0,0 +1,5 @@ +ostree admin init-fs

    Name

    ostree-admin-init-fs — Initialize a new root filesystem

    Synopsis

    ostree admin init-fs [OPTIONS...] {PATH}

    Description

    + Initialize an empty physical root filesystem in the designated PATH, with normal toplevels and correct permissions for each directory. Primarily useful for operating system installers. +

    Example

    $ mkdir /example

    $ ostree admin init-fs /example

    $ ls /example

    + boot dev home ostree proc root run sys tmp +

    diff --git a/man/ostree-admin-instutil.html b/man/ostree-admin-instutil.html new file mode 100644 index 0000000000..fa486faabc --- /dev/null +++ b/man/ostree-admin-instutil.html @@ -0,0 +1,10 @@ +ostree admin instutil

    Name

    ostree-admin-instutil — Utility functions intended primarily for operating system installation programs

    Synopsis

    ostree admin instutil {SUBCOMMAND} [ARGS]

    Description

    + Use the subcommands to toggle admin installation utilities for selinux policies and kernel arguments. +

    Subcommands

    selinux-ensure-labeled [SUBPATH PREFIX]

    + Ensure all files and directories are labeled according to SELinux policy of the first deployment. +

    set-kargs [--merge] [--import-proc-cmdline] [--append="NAME=VALUE"] [--replace="NAME=VALUE"] [MORE_APPEND_ARGS]

    + Replace the kernel arguments of the default deployment. The new arguments are based + on an empty list (the default), the current options (--merge), or the arguments + of the loaded kernel (--import-proc-cmdline), and new options either are added to the + end (--append="NAME=VALUE") or replace existing arguments of the same name (--replace="NAME=VALUE"). +

    diff --git a/man/ostree-admin-lock-finalization.html b/man/ostree-admin-lock-finalization.html new file mode 100644 index 0000000000..bd9fc87cca --- /dev/null +++ b/man/ostree-admin-lock-finalization.html @@ -0,0 +1,14 @@ +ostree admin lock-finalization

    Name

    ostree-admin-lock-finalization — Change whether staged deployment will be queued for next boot

    Synopsis

    ostree admin lock-finalization [OPTIONS...]

    Description

    + This command requires a staged deployment. By default, this command ensures the deployment + will be set into a "finalization locked" state, which means it will not be queued for the next boot by default. +

    + This is the same as the --lock-finalization argument for ostree admin deploy, + which is the recommended way to use this feature in a race-free way. +

    + However more commonly, one will use the --unlock argument for this command to later unlock + a deployment which was finalization locked. +

    Options

    --sysroot="PATH"

    + Path to the system to use rather than the current one. +

    --unlock,-u

    + Unlock the deployment finalization state. +

    diff --git a/man/ostree-admin-os-init.html b/man/ostree-admin-os-init.html new file mode 100644 index 0000000000..1b49f470f7 --- /dev/null +++ b/man/ostree-admin-os-init.html @@ -0,0 +1,3 @@ +ostree admin os-init

    Name

    ostree-admin-os-init — Soft-deprecated alias for stateroot-init

    Synopsis

    ostree admin os-init {STATEROOT}

    Description

    + This is a soft-deprecated alias for stateroot-init. Please see the documentation for that. +

    diff --git a/man/ostree-admin-pin.html b/man/ostree-admin-pin.html new file mode 100644 index 0000000000..5f0c29c0e1 --- /dev/null +++ b/man/ostree-admin-pin.html @@ -0,0 +1,9 @@ +ostree admin pin

    Name

    ostree-admin-pin — Explicitly retain deployment at a given index

    Synopsis

    ostree admin pin {INDEX}

    Description

    + Ensures the deployment at INDEX, will not be garbage + collected by default. This is termed "pinning". If the + -u option is provided, undoes a pinning operation. + INDEX can be >= 0 or one of booted, pending or + rollback strings. +

    Options

    --unpin,-u

    + Undoes a pinning operation. +

    diff --git a/man/ostree-admin-post-copy.html b/man/ostree-admin-post-copy.html new file mode 100644 index 0000000000..ed52b68818 --- /dev/null +++ b/man/ostree-admin-post-copy.html @@ -0,0 +1,7 @@ +ostree admin post-copy

    Name

    ostree-admin-post-copy — Fix up sysroot after a (file based) copy

    Synopsis

    ostree admin post-copy [OPTIONS...]

    Description

    + Applies any fixes to a sysroot that are needed after having copyed it file by file. + This includes enabling fs-verity to any files that lack it, which can happen if + you copy a file. +

    Options

    --sysroot="PATH"

    + Path to the system to use rather than the current one. +

    diff --git a/man/ostree-admin-set-default.html b/man/ostree-admin-set-default.html new file mode 100644 index 0000000000..8051b205e4 --- /dev/null +++ b/man/ostree-admin-set-default.html @@ -0,0 +1,16 @@ +ostree admin set-default

    Name

    ostree-admin-set-default — Make deployment at a given index the default for the next boot

    Synopsis

    ostree admin set-default {INDEX}

    Description

    + Make the deployment at INDEX the default for the next boot. +

    Example

    $ ostree admin status

    +        * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: exampleos/buildmain/x86_64-runtime
    +          exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
    +            origin refspec: exampleos/buildmain/x86_64-runtime
    +

    $ ostree admin set-default 1

    +        Transaction complete; bootconfig swap: deployment count change: 0
    +

    $ ostree admin status

    + exampleos ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0 + origin refspec: exampleos/buildmain/x86_64-runtime + * exampleos 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0 + origin refspec: exampleos/buildmain/x86_64-runtime +
    +
    diff --git a/man/ostree-admin-set-origin.html b/man/ostree-admin-set-origin.html new file mode 100644 index 0000000000..6d8f447e34 --- /dev/null +++ b/man/ostree-admin-set-origin.html @@ -0,0 +1,12 @@ +ostree admin set-origin

    Name

    ostree-admin-set-origin — Change the "origin" (location for upgrades)

    Synopsis

    ostree admin set-origin {REMOTENAME} {URL} [BRANCH]

    Description

    + Add a new remote named + REMOTENAME (if it does not + already exist). Then change the origin file for the + current deployment. This is the ref that will be + "tracked" and upgraded with ostree admin + upgrade. +

    Options

    --set=KEY=VALUE

    + Set an option for the remote. +

    --index=INDEX

    Change the origin of the deployment + numbered INDEX (starting + from 0).

    Example

    $ ostree admin set-origin exampleos http://os.example.com/repo exampleos/10.0/main/router

    diff --git a/man/ostree-admin-stateroot-init.html b/man/ostree-admin-stateroot-init.html new file mode 100644 index 0000000000..18686ce844 --- /dev/null +++ b/man/ostree-admin-stateroot-init.html @@ -0,0 +1,9 @@ +ostree admin stateroot-init

    Name

    ostree-admin-stateroot-init — Initialize empty state for a given operating system

    Synopsis

    ostree admin stateroot-init {STATEROOT}

    Description

    + Initializes an new stateroot (AKA "osname") for an operating system. + Ensures that the core subdirectories of /var (/tmp, /lib, /run, and + /lock) exist and initialize the given STATEROOT as OSTree stateroot. + Each deployment location is comprised of a single shared + var and a set of deployments (chroots). +

    Example

    $ ostree admin stateroot-init exampleos

    +        ostree/deploy/exampleos initialized as OSTree stateroot
    +    
    diff --git a/man/ostree-admin-status.html b/man/ostree-admin-status.html new file mode 100644 index 0000000000..51b959fa4e --- /dev/null +++ b/man/ostree-admin-status.html @@ -0,0 +1,25 @@ +ostree admin status

    Name

    ostree-admin-status — List deployments

    Synopsis

    ostree admin status

    Description

    + Lists the deployments available to be booted into. Includes osname, the checksum followed by the deploy serial, and the refspec. An asterisk indicates the current booted deployment. +

    Options

    --sysroot="PATH"

    + Create a new OSTree sysroot at PATH +

    -V, --verify

    + Print the commit verification status +

    -S, --skip-signatures

    + Skip signatures in output +

    -D, --is-default

    + Output the string default if the default deployment + is the booted one, not-default if we are booted in + a non-default deployment (e.g. the user interactively chose a + different entry in the bootloader menu, or the bootloader rolled back + automatically, etc.). If we are not in a booted OSTree system, an + error is returned. +

    -v, --verbose

    + Print debug information during command processing +

    --version

    + Print version information and exit +

    Example

    $ ostree admin status

    +        * gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +          gnome-ostree ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +
    diff --git a/man/ostree-admin-switch.html b/man/ostree-admin-switch.html new file mode 100644 index 0000000000..4408b3a658 --- /dev/null +++ b/man/ostree-admin-switch.html @@ -0,0 +1,5 @@ +ostree admin switch

    Name

    ostree-admin-switch — Construct new tree from current origin and deploy it, if it changed

    Synopsis

    ostree admin switch {REF}

    Description

    + Choose a different REF from the current remote to track. This is the ref that will be "tracked" and upgraded with ostree admin upgrade. Like an upgrade, the operating system state will be preserved. +

    Options

    --os="STATEROOT"

    + Use a different operating system root than the current one. +

    Example

    $ ostree admin switch fedostree/20/workstation/gnome/core

    diff --git a/man/ostree-admin-undeploy.html b/man/ostree-admin-undeploy.html new file mode 100644 index 0000000000..21f930ec6f --- /dev/null +++ b/man/ostree-admin-undeploy.html @@ -0,0 +1,15 @@ +ostree admin undeploy

    Name

    ostree-admin-undeploy — Delete deployment at a given index

    Synopsis

    ostree admin undeploy {INDEX}

    Description

    + Deletes the deployment at INDEX. INDEX must be in range and not reference the currently booted deployment. +

    Example

    $ ostree admin status

    +        * gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +          gnome-ostree ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +

    $ ostree admin undeploy 1

    +        Transaction complete; bootconfig swap: no deployment count change: -1)
    +        Freed objects: 326.5 kB
    +        Deleted deployment ce19c41036cc45e49b0cecf6b157523c2105c4de1c.0
    +

    $ ostree admin status

    +        * gnome-ostree 67e382b11d213a402a5313e61cbc69dfd5ab93cb07.0
    +            origin refspec: gnome-ostree/buildmain/x86_64-runtime
    +
    diff --git a/man/ostree-admin-unlock.html b/man/ostree-admin-unlock.html new file mode 100644 index 0000000000..805e0d6dae --- /dev/null +++ b/man/ostree-admin-unlock.html @@ -0,0 +1,16 @@ +ostree admin unlock

    Name

    ostree-admin-unlock — Prepare the current deployment for hotfix or development

    Synopsis

    ostree admin unlock [OPTIONS...]

    Description

    + Remove the read-only bind mount on /usr + and replace it with a writable overlay filesystem. This + default invocation of "unlock" is intended for + development/testing purposes. All changes in the overlay + are lost on reboot. However, this command also supports + "hotfixes", see below. +

    Options

    --hotfix

    If this option is provided, the + current deployment will be cloned as a rollback + target. This option is intended for things like + emergency security updates to userspace components + such as sshd. The semantics here + differ from the default "development" unlock mode + in that reboots will retain any changes (which is what + you likely want for security hotfixes). +

    diff --git a/man/ostree-admin-upgrade.html b/man/ostree-admin-upgrade.html new file mode 100644 index 0000000000..451c39d7e2 --- /dev/null +++ b/man/ostree-admin-upgrade.html @@ -0,0 +1,25 @@ +ostree admin upgrade

    Name

    ostree-admin-upgrade — Construct new tree from current origin and deploy it, if it changed

    Synopsis

    ostree admin upgrade [OPTIONS...]

    Description

    + Downloads the latest version of the current ref from the build + server and deploys it, if it changed. Reboot the machine for the + changes to take effect. These phases can be split via + --pull-only and --deploy-only. +

    Options

    --os="STATEROOT"

    + Use a different operating system root than the current one. +

    --pull-only

    Only perform a pull into the repository; do not + create a deployment. This option can hence safely be used in a + background scheduled job with the assurance of not changing + system state.

    --deploy-only

    Create a new deployment from the latest commit + in the tracked origin refspec. This option is intended to be used + by a scheduled system that detected changes via --pull-only, + and is ready to deploy them.

    --stage

    + Perform deployment finalization at shutdown time. Recommended, + and will likely become the default in the future. +

    --reboot,-r

    + Reboot after a successful upgrade. +

    --allow-downgrade

    + Permit deployment of chronologically older trees. +

    --override-commit="CHECKSUM"

    + Deploy CHECKSUM instead of the latest tree. +

    Example

    $ ostree admin upgrade

    +        No update available.
    +
    diff --git a/man/ostree-admin.html b/man/ostree-admin.html new file mode 100644 index 0000000000..f6c881aa56 --- /dev/null +++ b/man/ostree-admin.html @@ -0,0 +1,9 @@ +ostree admin

    Name

    ostree-admin — Use one of the ostree admin commands

    Synopsis

    ostree admin {SUBCOMMAND}

    Description

    + Use ostree admin subcommands. +

    Subcommands

    • cleanup

    • config-diff

    • deploy

    • init-fs

    • instutil

    • os-init

    • pin

    • post-copy

    • set-origin

    • status

    • switch

    • undeploy

    • unlock

    • upgrade

    + View manpages for each admin subcommand using, for example: +

    + $ man ostree-admin cleanup +

    Options

    --help, -h

    Usage help

    --sysroot="PATH"

    Creates a new OSTree sysroot at PATH

    --print-current-dir

    + Prints the full path to the deployment directory for the currently active deployment in the specified sysroot to standard out. This is incompatible with specifying a subcommand. +

    diff --git a/man/ostree-cat.html b/man/ostree-cat.html new file mode 100644 index 0000000000..b8d5194624 --- /dev/null +++ b/man/ostree-cat.html @@ -0,0 +1,5 @@ +ostree cat

    Name

    ostree-cat — Display or concatenate contents of files

    Synopsis

    ostree cat {COMMIT} {PATH...}

    Description

    + This command functions much like the typical Unix "cat" command, in that it displays the contents of a file, or concatenates them given two or more files. However, this command requires the user to specify a commit - a checksum or refspec corresponding to a given build. If you use a refspec, OSTree will refer to the most recent commit, unless you specify a parent build using the carat (^) at the end of the refspec. It will then operate the command in that given commit. +

    Example

    $ ostree cat my-branch helloworld.txt

    +        Hello, world!
    +
    diff --git a/man/ostree-checkout.html b/man/ostree-checkout.html new file mode 100644 index 0000000000..1dac038445 --- /dev/null +++ b/man/ostree-checkout.html @@ -0,0 +1,50 @@ +ostree checkout

    Name

    ostree-checkout — Check out a commit into a filesystem

    Synopsis

    ostree checkout [OPTIONS...] {COMMIT} [DESTINATION]

    Description

    + Checks out the given commit into the filesystem under directory DESTINATION. If DESTINATION is not specified, the COMMIT will become the destination checkout target. If COMMIT destination already exists, command will error unless --union option is selected. +

    Options

    --user-mode, -U

    + Do not change file ownership or initialize extended attributes. +

    --subpath="PATH"

    + Checkout sub-directory PATH. +

    --union

    + Keep existing directories and unchanged files, overwrite existing files. +

    --union-add

    + Keep existing directories and files. +

    --union-identical

    Like --union, but error out + if a file would be replaced with a different file. Add new files + and directories, ignore identical files, and keep existing + directories. Requires -H.

    --whiteouts

    + Process whiteout files (Docker style). +

    --process-passthrough-whiteouts

    + Enable overlayfs whiteout extraction into 0:0 character devices. + Overlayfs whiteouts are encoded inside ostree as .ostree-wh.filename + and extracted as 0:0 character devices. This is useful to carry + container storage embedded into ostree. +

    --allow-noent

    + Do nothing if specified path does not exist. +

    --from-stdin

    + Process many checkouts from standard input. +

    --from-file="FILE"

    + Process many checkouts from input file. +

    --fsync="POLICY"

    + POLICY is a boolean which specifies whether fsync should be + used or not. Default to true. +

    --require-hardlinks, + -H

    + Do not fall back to full copies if hardlinking fails. +

    --force-copy-zerosized, + -z

    + This option does nothing; the functionality is now always on by default. +

    --force-copy, -C

    + Never hardlink (but may reflink if available). +

    --bareuseronly-dirs, + -M

    + Suppress mode bits outside of 0775 for directories (suid, + world writable, etc.). +

    --skip-list="FILE"

    + Skip checking out the absolute file paths listed in FILE, + one per line. +

    --selinux-policy

    + Set SELinux labels based on policy in root filesystem PATH + (may be /). This implies --force-copy. +

    Example

    $ ostree checkout my-branch

    $ ls

    +        file1file2my-branch
    +
    diff --git a/man/ostree-checksum.html b/man/ostree-checksum.html new file mode 100644 index 0000000000..37c2159862 --- /dev/null +++ b/man/ostree-checksum.html @@ -0,0 +1,7 @@ +ostree checksum

    Name

    ostree-checksum — Checksum a file or directory

    Synopsis

    ostree checksum {PATH}

    Description

    + Generates a checksum for a given file or directory. +

    Options

    --ignore-xattrs

    + Ignore extended attributes when checksumming. +

    Example

    $ ostree checksum file1

    +        67e382b11d213a402a5313e61cbc69dfd5ab93cb07fbb8b71c2e84f79fa5d7dc
    +
    diff --git a/man/ostree-commit.html b/man/ostree-commit.html new file mode 100644 index 0000000000..e92c573544 --- /dev/null +++ b/man/ostree-commit.html @@ -0,0 +1,89 @@ +ostree commit

    Name

    ostree-commit — Commit a new revision

    Synopsis

    ostree commit [OPTIONS...] --branch= {BRANCH} [PATH]

    Description

    + This allows you to commit changes to a branch. The specification of the branch is required. The command will print the checksum of a successful commit. +

    Options

    --subject, -s="SUBJECT"

    + One line subject. (optional) +

    --body, -m="BODY"

    + Full description. (optional) +

    --body-file, -F="FILE"

    + Full commit description from a file. (optional) +

    --editor, -e

    + Open a text editor for the commit description. It will use OSTREE_EDITOR, VISUAL, EDITOR, or vi, in descending order of preference. The commit will be aborted if the message is left empty. +

    --branch, -b="BRANCH"

    + Branch. Required, unless --orphan is given. +

    --parent="COMMIT"

    + Parent checksum or "none" to explicitly use no parent. If not specified, BRANCH is used as parent (no parent in case BRANCH does not exist). +

    --tree="dir=PATH" or "tar=TARFILE" or "ref=COMMIT"

    + Overlay the given argument as a tree. When committing an archive, the TARFILE can be specified as - to read the archive from standard input. +

    --base="REV"

    + Start from the content in a commit. This differs from --tree=ref=REV in that no commit modifiers are applied. This is usually what you want when + creating a derived commit. This is also used for --selinux-policy-from-base. +

    --add-metadata-string="KEY=VALUE"

    + Add a key/value pair to metadata. Can be specified multiple times. +

    --add-metadata="KEY=VALUE"

    + Add a key/value pair to metadata, where the KEY is a string, and VALUE is g_variant_parse() formatted. Can be specified multiple times. +

    --keep-metadata="KEY"

    + Keep metadata KEY and its associated VALUE from parent. Can be specified multiple times. +

    --add-detached-metadata-string="KEY=VALUE"

    + Add a key/value pair to detached metadata. +

    --owner-uid="UID"

    + Set file ownership user id. +

    --owner-gid="GID"

    + Set file ownership group id. +

    --no-xattrs

    + Do not import extended attributes. +

    --selinux-labeling-epoch0 | 1

    + When SELinux labeling is enabled, epoch 1 ensures that /usr/etc is labeled as if it was /etc. +

    --bootable

    + Inject standard metadata for a bootable Linux filesystem tree. +

    --link-checkout-speedup

    + Optimize for commits of trees composed of hardlinks into the repository. +

    --tar-autocreate-parents

    + When loading tar archives, automatically create parent directories as needed. +

    --skip-if-unchanged

    + If the contents are unchanged from previous commit, do nothing. +

    --consume

    + When committing from a local directory (i.e. not an archive or --tree=ref), + assume ownership of the content. This may simply involve deleting it, + but if possible, the content may simply be rename()ed + into the repository rather than creating a new copy. +

    --statoverride="PATH"

    + File containing list of modifications to make permissions (file mode in + decimal, followed by space, followed by file path). The specified mode + is ORed with the file's original mode unless preceded by "=". +

    --skip-list="PATH"

    + File containing list of file paths to skip (one path per line). +

    --table-output

    + Output more information in a KEY: VALUE format. +

    --generate-sizes

    + Generate size information along with commit metadata. +

    --gpg-sign="KEY-ID"

    + GPG Key ID with which to sign the commit (if have GPGME - GNU Privacy Guard Made Easy). +

    --gpg-homedir="HOMEDIR"

    + GPG home directory to use when looking for keyrings (if have GPGME - GNU Privacy Guard Made Easy). +

    --timestamp="TIMESTAMP"

    + Override the timestamp of the commit to TIMESTAMP. +

    --orphan

    + Create a commit without writing to a ref (branch) +

    --fsync="POLICY"

    + POLICY is a boolean which specifies whether fsync should be used or not. Default to true. +

    -s, --sign-type

    + Use particular signature engine. Currently + available ed25519 and dummy + signature types. + + The default is ed25519 . +

    --sign-from-file="PATH"

    + This will read a key (corresponding to the provided --sign-type from the provided path. The key should be base64 encoded. +

    --sign="KEY-ID"

    + In new code, avoid using this because passing private keys via command line arguments + are prone to leakage in logs and process listings. +

    + The KEY-ID is: +

    for ed25519:

    + base64-encoded secret key for commit signing. +

    for dummy:

    + ASCII-string used as secret key. +

    +

    Example

    $ ostree commit --branch=my-branch --subject="Initial commit"

    +        67e382b11d213a402a5313e61cbc69dfd5ab93cb07fbb8b71c2e84f79fa5d7dc
    +
    diff --git a/man/ostree-config.html b/man/ostree-config.html new file mode 100644 index 0000000000..07efa02370 --- /dev/null +++ b/man/ostree-config.html @@ -0,0 +1,14 @@ +ostree config

    Name

    ostree-config — Change configuration settings

    Synopsis

    ostree config get {GROUPNAME.KEYNAME}

    ostree config get { --group=GROUPNAME} { KEYNAME}

    ostree config set {GROUPNAME.KEYNAME} {VALUE}

    ostree config set { --group=GROUPNAME} { KEYNAME} {VALUE}

    ostree config unset {GROUPNAME.KEYNAME}

    ostree config unset { --group=GROUPNAME} { KEYNAME}

    Description

    • + ostree config get displays the value of + KEYNAME in the group GROUPNAME +

    • + ostree config set sets the value of + KEYNAME in the group GROUPNAME + to VALUE . +

    • + ostree config unset removes the key + KEYNAME from the group GROUPNAME + so that OSTree uses the default value for it. It is not an + error for the specified GROUPNAME or + KEYNAME not to exist. +

    Example

    $ ostree config get core.mode

    bare

    $ ostree config set --group='remote "myremote"' url http://example.com/repo

    $ ostree config unset core.lock-timeout-secs

    diff --git a/man/ostree-create-usb.html b/man/ostree-create-usb.html new file mode 100644 index 0000000000..cb7e1f30f3 --- /dev/null +++ b/man/ostree-create-usb.html @@ -0,0 +1,35 @@ +ostree create-usb

    Name

    ostree-create-usb — Put the given refs on an external drive for P2P distribution.

    Synopsis

    ostree create-usb [OPTIONS...] {MOUNT-PATH} {COLLECTION-ID REF} [COLLECTION-ID REF...]

    Description

    + This command creates a repository in MOUNT-PATH and pulls the given + REF(s) into it so they can be found and pulled from (perhaps by another computer that's offline). + See + ostree-find-remotes(1) + for more information on P2P distribution. +

    + In order for ostree to pull refs from a mounted filesystem (such as + a USB drive) the repo must be in a standard location. Specifically, + subdirectories of .ostree/repos.d are checked, + then .ostree/repo, ostree/repo, + and var/lib/flatpak/repo are checked. By default + ostree create-usb uses .ostree/repo, + but if you specify another location using --destination-repo + a symbolic link will be created for you in .ostree/repos.d. +

    + This command will regenerate the summary file + in the destination repo so that it stays accurate, so you shouldn't + try to use summary signatures in the destination repo. This + shouldn't be a concern because clients that support pulling from + USB mounts use signed per-repo and per-commit metadata instead of + summary signatures. +

    Options

    --disable-fsync

    + Do not invoke fsync(). +

    --destination-repo=DEST

    + Create the repository in DEST under MOUNT-PATH, rather than + the default location. +

    --commit=COMMIT

    + Pull COMMIT instead of whatever REF points to. This can only + be used if a single ref is specified. +

    Example

    ostree --repo=/var/lib/flatpak/repo create-usb /run/media/mwleeds/f6d04c7a-60f6-4ba3-bb96-0f40498675be com.exampleos.Apps app/org.kde.Khangman/x86_64/stable com.exampleos.Apps ostree-metadata com.exampleos.Apps appstream/x86_64

    +
    +5 metadata, 213 content objects imported; 1 KiB transferred in 1 seconds                                                                                                                      Copied 3/3 refs successfully from ‘/var/lib/flatpak/repo’ to ‘.ostree/repo’ repository in ‘/run/media/mwleeds/f6d04c7a-60f6-4ba3-bb96-0f40498675be’.
    +
    +
    diff --git a/man/ostree-diff.html b/man/ostree-diff.html new file mode 100644 index 0000000000..a394d9ffe3 --- /dev/null +++ b/man/ostree-diff.html @@ -0,0 +1,17 @@ +ostree diff

    Name

    ostree-diff — Compare a directory against a revision

    Synopsis

    ostree diff [OPTIONS...] {REV_OR_DIR} {REV_OR_DIR}

    Description

    + Compare a directory or revision against another directory or revision. If REV_OR_DIR starts with `/` or `./`, it is interpreted as a directory, otherwise a revision. Shows files and directories modified, added, and deleted. If there is a file in the second REV_OR_DIR not in the first, it will show with an "A" for "added". If a file in the first REV_OR_DIR is not in the second, it shows "D" for "deleted". "M" for "modified" will also show. +

    Options

    --stats

    + Print various statistics. +

    --fs-diff

    + Print filesystem diff. +

    --owner-uid

    + Use file ownership user id for local files. +

    --owner-gid

    + Use file ownership group id for local files. +

    Example

    $ ostree diff my-branch^ my-branch

    +        A   /testdirectory
    +        M   /helloworld.txt
    +

    $ ostree diff my-branch my-branch^

    +        D   /testdirectory
    +        M   /helloworld.txt
    +
    diff --git a/man/ostree-export.html b/man/ostree-export.html new file mode 100644 index 0000000000..501fab8370 --- /dev/null +++ b/man/ostree-export.html @@ -0,0 +1,5 @@ +ostree export

    Name

    ostree-export — Generate a tar archive from an OSTree commit

    Synopsis

    ostree export [OPTIONS...] {BRANCH}

    Description

    + This command generates a GNU tar formatted archive from an + OSTree commit. This is useful for cases like backups, + converting OSTree commits into Docker images, and the like. +

    Example

    $ ostree export exampleos/x86_64/standard | gzip > exampleos-standard.tar.gz

    diff --git a/man/ostree-find-remotes.html b/man/ostree-find-remotes.html new file mode 100644 index 0000000000..063b983bac --- /dev/null +++ b/man/ostree-find-remotes.html @@ -0,0 +1,47 @@ +ostree find-remotes

    Name

    ostree-find-remotes — Find remotes to serve the given refs

    Synopsis

    ostree find-remotes [OPTIONS...] {COLLECTION-ID} {REF} [COLLECTION-ID REF...]

    Description

    + OSTree has the ability to pull not just from the configured remote + servers but also from peer computers on the LAN and from mounted + filesystems such as USB drives. This functionality requires the use + of collection IDs and GPG verification. +

    + The find-remotes command searches for remotes + which claim to provide one or more of the given COLLECTION-ID REF + pairs and prints information about them, with remotes sorted by + latency (Mounts > LAN > Internet). By default, OSTree searches for + remotes in configuration files, on mounted filesystems (in a + well-known location), and on the LAN using Avahi. Searching for LAN + remotes requires OSTree to have been compiled with Avahi support, + and it requires an Avahi daemon to be running. You can override the + default set of finders (sources for remotes) using the + --finders option documented below. +

    + The create-usb command is the recommended way to + put refs on a USB such that find-remotes will + discover them. See + ostree-create-usb(1). +

    Options

    --cache-dir=DIR

    + Use an alternate cache directory in DIR. +

    --disable-fsync

    + Do not invoke fsync(). +

    --finders=FINDERS

    + Use the specified comma separated list of finders rather than + the default set. Possible values: config, + lan, and mount (or any + combination thereof). +

    --pull

    + Pull the most recent commit found for each ref. +

    --mirror

    + Do a mirror pull (see the documentation for + ostree pull --mirror). This option can + only be used in combination with --pull. +

    Example

    $ ostree find-remotes --finders=mount,lan com.exampleos.Os exampleos/x86_64/standard

    +Result 0: http://10.0.64.202:43381/0
    + - Finder: OstreeRepoFinderAvahi
    + - Keyring: exampleos.trustedkeys.gpg
    + - Priority: 60
    + - Summary last modified: 2018-01-12T19:00:28Z
    + - Refs:
    +    - (com.exampleos.Os, exampleos/x86_64/standard) = c91acd964b3fda561b87bfb7f7c80e36220d76b567f0ce90c0e60742ef33c360
    +
    +1/1 refs were found.
    +
    diff --git a/man/ostree-fsck.html b/man/ostree-fsck.html new file mode 100644 index 0000000000..202353a978 --- /dev/null +++ b/man/ostree-fsck.html @@ -0,0 +1,25 @@ +ostree fsck

    Name

    ostree-fsck — Check the repository for consistency

    Synopsis

    ostree fsck [OPTIONS...]

    Description

    + Checks the repository to verify the content integrity of commit objects. Looks for missing and corrupted objects and metadata, and validates directory structure and metadata. +

    Options

    --quiet,-q

    + Only print error messages. +

    --delete

    + Remove corrupted objects. +

    --add-tombstones

    + Add tombstone commit for referenced but missing commits. +

    --verify-bindings

    + Verify that the commits pointed to by each ref have that + ref in the binding set. You should usually add this + option; it only defaults to off for backwards compatibility. +

    --verify-back-refs

    + Verify that all the refs listed in a commit’s ref-bindings + point to that commit. This cannot be used in repositories + where the target of refs is changed over time as new commits + are added, but can be used in repositories which are + regenerated from scratch for each commit. + Implies --verify-bindings as well. +

    Example

    $ ostree fsck

    +        Enumerating objects...
    +        Verifying content integrity of of 2 commit objects
    +        0/2572 objects
    +        2571/2572 objects
    +
    diff --git a/man/ostree-gpg-sign.html b/man/ostree-gpg-sign.html new file mode 100644 index 0000000000..1e23304aaf --- /dev/null +++ b/man/ostree-gpg-sign.html @@ -0,0 +1,10 @@ +ostree gpg-sign

    Name

    ostree-gpg-sign — Sign a commit

    Synopsis

    ostree gpg-sign [OPTIONS...] {COMMIT} {KEY-ID...}

    Description

    + Add a new signature to a commit for each specified GPG key. + + Note that currently, this will append a new signature even if + the commit is already signed with a given key. +

    Options

    --delete

    + Delete signatures having any of the GPG KEY-IDs. +

    --gpg-homedir="HOMEDIR"

    + GPG Homedir to use when looking for keyrings. +

    diff --git a/man/ostree-init.html b/man/ostree-init.html new file mode 100644 index 0000000000..ae1a7bd4bc --- /dev/null +++ b/man/ostree-init.html @@ -0,0 +1,33 @@ +ostree init

    Name

    ostree-init — Initialize a new empty repository

    Synopsis

    ostree init [OPTIONS...]

    Description

    + Creates a new empty repository. +

    Options

    --mode="MODE"

    + Initialize repository in given mode + (bare, bare-user, + bare-user-only, archive). + The default is bare. Note that for + archive the repository configuration file + will actually have archive-z2, as that's + the historical name.

    See the manual for differences between these modes. + Briefly, bare mode stores files as they + are, so they can be directly hardlinked, + bare-user uses extended attributes to + store ownership and xattr information, allowing non-root + operations, bare-user-only does not store + ownership information, and archive stores + files compressed, to be served over the network. +

    --collection-id=COLLECTION-ID

    + Set the collection ID of the repository. Remotes in clones + of this repository must configure the same value in order to + pull refs which originated in this repository over peer to + peer.

    This collection ID must be persistent and globally + unique. It is formatted as a reverse DNS name (like a D-Bus + interface). It must be set to a reverse DNS domain under your + control.

    This option may be omitted (the default) to leave + peer to peer distribution unsupported for the repository. A + collection ID may be added to an existing repository in + future to enable peer to peer distribution from that point + onwards.

    If the collection ID is changed for the repository + in future, peer to peer distribution of refs from the + repository will break for all peers who do not update their + remote configuration to the new collection ID. +

    diff --git a/man/ostree-log.html b/man/ostree-log.html new file mode 100644 index 0000000000..b185ef8aa0 --- /dev/null +++ b/man/ostree-log.html @@ -0,0 +1,13 @@ +ostree log

    Name

    ostree-log — Show log starting at a commit or ref

    Synopsis

    ostree log [OPTIONS...] {REF}

    Description

    + Shows a log of commits to a given ref or branch. Includes commit checksum, timestamp, and commit message. +

    Options

    --raw

    + Show raw variant data. +

    Example

    $ ostree log my-branch

    +        commit 67e382b11d213a402a5313e61cbc69dfd5ab93cb07fbb8b71c2e84f79fa5d7dc
    +        Date:  2014-06-12 13:42:54 +0000
    +            This is the second commit
    +
    +        commit ce19c41036cc45e49b0cecf6b157523c2105c4de1ce30101def1f759daafcc3e
    +        Date:  2014-06-12 11:20:08 +0000
    +            Initial commit
    +
    diff --git a/man/ostree-ls.html b/man/ostree-ls.html new file mode 100644 index 0000000000..b0f9d4cac8 --- /dev/null +++ b/man/ostree-ls.html @@ -0,0 +1,17 @@ +ostree ls

    Name

    ostree-ls — List file paths

    Synopsis

    ostree ls [OPTIONS...] {COMMIT} [PATHS...]

    Description

    + Prints a list of file paths within the given commit, and within the given path(s) if specified. The first letter of the file line output specifies the type: "-" for regular file, "d" for directory, "l" for symbolic link. See EXAMPLE section for more detail on the specific output. +

    Options

    --dironly,-d

    + Do not recurse into directory arguments. +

    --recursive,-R

    + Print directories recursively. +

    --checksum,-C

    + Print checksum. +

    --xattrs,-X

    + Print extended attributes. +

    --nul-filenames-only

    + Print only filenames, NUL separated. +

    Example

    $ ostree ls my-branch

    +        d00644 0 0    0 /
    +        -00644 0 0    2 /helloworld.txt
    +        d00755 0 0    0 /testdirectory
    +

    Here, the first column is the file-type symbol (as explained in the DESCRIPTION section) followed by the S_IFMT file type. The next two columns (here: 0 0) are respectively the user ID and group ID for the file. After the break, the next number represents that file's standard size. The final column is the file path.

    diff --git a/man/ostree-prepare-root.html b/man/ostree-prepare-root.html new file mode 100644 index 0000000000..c962482572 --- /dev/null +++ b/man/ostree-prepare-root.html @@ -0,0 +1,63 @@ +ostree prepare-root

    Name

    ostree-prepare-root — Change the view of a mounted root filesystem to an ostree deployment

    Synopsis

    ostree prepare-root {TARGET}

    Description

    + At its core, ostree operates on an existing mounted filesystem. Tooling such + as ostree admin deploy will create a new directory that can be + used as a bootable target. This tool is designed to run in an initramfs and + set up "remapping" mounts as a view into that filesystem. +

    + As of more recently, this tool also has optional support for composefs, which + creates a distinct mount point layered on top of the underlying filesystem. +

    + The most common pattern today is to use systemd in an initramfs. The systemd + unit shipped upstream is ordered in this way: + + After=sysroot.mount and Before=initrd-root-fs.target +

    + When it runs, the mounted filesystem at the provided TARGET (usually /sysroot) + will be changed such that what appears at /sysroot is actually the + "deployment root" - i.e. a particular versioned subdirectory. What was formerly the + "physical root" i.e. the real root of the filesystem will appear as /sysroot/sysroot. +

    + For /var, by default a bind mount is created from the deployment root to /sysroot/var. +

    + A read-only bind mount is created over /sysroot/usr. The immutable bit (see chattr(1)) is set on the deployment + root, so this provides basic protection for filesystem mutation. If the sysroot.readonly + option is enabled, then /sysroot/sysroot is mounted read-only to provide further protection and a writable bind mount for + /sysroot/etc is created. +

    + Finally, when higher level tooling such as systemd performs a switch-root operation, what + was /sysroot becomes / and after the transition into + the real root, the system will be booted into the "deployment", which is a versioned immutable + filesystem tree. The ostree tooling running in the real root thereafter performs further changes + by operating on /sysroot which is now the "physical root". +

    Configuration

    + The /usr/lib/ostree/prepare-root.conf (or /etc/ostree/prepare-root.conf) config file is parsed by ostree-prepare-root. This file must + be present in the initramfs. The default dracut module will copy it from the real root if present. +

    sysroot.readonly

    A boolean value; the default is false unless composefs is enabled. If this is set to true, then the /sysroot mount point is mounted read-only.

    etc.transient

    A boolean value; the default is false. If this is set to true, then the /etc mount point is mounted transiently i.e. a non-persistent location.

    root.transient

    A boolean value; the default is false. + If this is set to true, then the / filesystem will be a writable overlayfs, + with the upper directory being a hidden directory (in the underlying system root filesystem) that will persist across reboots by default. + However, changes will be discarded on OS updates! +

    + Enabling this option can be very useful for cases such as packages (dpkg/rpm/etc) that write content into /opt, + particularly where they expect the target to be writable at runtime. To make that work, ensure that your /opt + directory is *not* a symlink to /var/opt, but is just an empty directory. +

    + Note the /usr mount point remains read-only by default. This option is independent of etc.transient and sysroot.readonly; + it is supported for example to have root.transient=true but etc.transient=false in which case changes to /etc continue + to persist across updates, with the default OSTree 3-way merge applied. +

    composefs.enabled

    This can be yes, no. maybe or + signed. The default is maybe. If set to yes or + signed, then composefs is always used, and the boot fails if it is not + available. Additionally if set to signed, boot will fail if the image cannot be + validated by a public key. If set to maybe, then composefs is used if supported. +

    composefs.keypath

    Path to a file with Ed25519 public keys in the initramfs, used if + composefs.enabled is set to signed. The default value for this is + /etc/ostree/initramfs-root-binding.key. For a valid signed boot the target OSTree + commit must be signed by at least one public key in this file, and the commitfs digest listed in the + commit must match the target composefs image.

    systemd

    + As mentioned above, this tool comes with a systemd unit file ostree-prepare-root.service + and it is primarily expected to be invoked this way. +

    Composefs

    + The default for ostree is to create a plain hardlinked filesystem tree. + composefs support is currently experimental; see the upstream doc/composefs.md + for more information on using it. +

    diff --git a/man/ostree-prune.html b/man/ostree-prune.html new file mode 100644 index 0000000000..9a02bcc6d1 --- /dev/null +++ b/man/ostree-prune.html @@ -0,0 +1,31 @@ +ostree prune

    Name

    ostree-prune — Search for unreachable objects

    Synopsis

    ostree prune [OPTIONS...]

    Description

    + This searches for unreachable objects in the current repository. If unreachable objects are found, the command delete them to free space. If the --no-prune option is invoked, the command will just print unreachable objects and recommend deleting them. +

    Options

    --no-prune

    + Only display unreachable objects; don't delete. +

    --refs-only

    + Only compute reachability via refs. +

    --delete-commit=COMMIT

    + Specify a COMMIT to delete. +

    --keep-younger-than=DATE

    + All commits older than DATE will be + pruned. The format of DATE is the same as that + accepted by GNU date utility - for more information + see info date. +

    --depth=DEPTH

    + Only traverse DEPTH (integer) parents for each commit (default: -1=infinite). +

    --static-deltas-only=DEPTH

    + This option may currently only be used in combination with + --delete-commit. Previous versions of ostree silently accepted + the option without that, and ignored it. However, there are desired use + cases for pruning just static deltas (while retaining the commits), and it's + likely at some point this option will be supported for use cases outside of just + --delete-commit. +

    --commit-only

    + Only traverse and delete commit objects. This leaves orphaned meta and + content objects, which can be cleaned up with another prune invocation. + One may want to use this option to cheaply delete multiple commits, + and then clean up with a more expensive prune at the end. +

    Example

    $ ostree prune

    +        Total objects: 25627
    +        No unreachable objects
    +
    diff --git a/man/ostree-pull-local.html b/man/ostree-pull-local.html new file mode 100644 index 0000000000..2d52b523c7 --- /dev/null +++ b/man/ostree-pull-local.html @@ -0,0 +1,15 @@ +ostree pull-local

    Name

    ostree-pull-local — Copy data from a source repository

    Synopsis

    ostree pull-local [OPTIONS...] {SOURCE_REPO} [REFS...]

    Description

    + Copies data from a given repository; optimized for copies only between repositories on the same system. +

    Options

    --remote="REMOTE"

    + Add REMOTE to refspec. +

    --disable-fsync

    + Do no invoke fsync(). +

    --untrusted

    + Do not trust source, verify checksums and don't hardlink into source. +

    --disable-verify-bindings

    + Disable verification of commit metadata bindings. +

    Example

    $ ostree pull-local /ostree/repo

    +        Enumerating objects...
    +        pull: 25709/25709 scanned, 0 objects copied
    +        Writing 5 refs
    +
    diff --git a/man/ostree-pull.html b/man/ostree-pull.html new file mode 100644 index 0000000000..5fd2dba57e --- /dev/null +++ b/man/ostree-pull.html @@ -0,0 +1,63 @@ +ostree pull

    Name

    ostree-pull — Download data from a remote repository

    Synopsis

    ostree pull {REMOTE} [BRANCH]

    Options

    --commit-metadata-only

    + Fetch only the commit metadata. +

    --cache-dir=DIR

    + Use an alternate cache directory in DIR. +

    --disable-fsync

    + Do no invoke fsync(). +

    --localcache-repo

    + Like git's clone --reference. Reuse the provided + OSTree repo as a local object cache when doing HTTP fetches. + May be specified multiple times. +

    --untrusted

    + Do not trust local sources, verify checksums and don't hardlink into source. +

    --disable-static-deltas

    + Do not use static deltas. +

    --mirror

    + Write refs suitable for a mirror, i.e. refs are stored in the + heads/ directory rather than the + remotes/ directory. This makes the target repo + suitable to be exported for other clients to pull from as an ostree + remote. If no specific refs are specified, all refs will be fetched (the + remote must have a summary file present). +

    --subpath=SUBPATH

    + Only pull the provided subpath. +

    --depth=DEPTH

    + Traverse DEPTH parents (-1=infinite) (default: 0). +

    --network-retries=N

    + Specifies how many times each download should be retried upon error (default: 5) +

    --disable-retry-on-network-errors

    + Do not retry when network issues happen, instead fail automatically. (Currently only affects libcurl) +

    --low-speed-limit-bytes=N

    + The average transfer speed per second of a transfer during the + time set via 'low-speed-time-seconds' for libcurl to abort + (default: 1000) +

    --low-speed-time-seconds=N

    + The time in number seconds that the transfer speed should be + below the 'low-speed-limit-bytes' setting for libcurl to abort + (default: 30) +

    --max-outstanding-fetcher-requests=N

    + The max amount of concurrent connections allowed. (default: 8) +

    --disable-verify-bindings

    + Disable verification of commit metadata bindings. +

    Description

    + Without --mirror, this command will create new refs + under remotes/REMOTE/ directory + for each pulled branch unless they are already created. Such + refs can be then referenced by REMOTE:BRANCH in + ostree subcommands (e.g. ostree log origin:exampleos/x86_64/standard). +

    + This command can retrieve just a specific commit, or go all + the way to performing a full mirror of the remote + repository. If no BRANCH is specified, + all configured branches are retrieved. +

    + A special syntax in the @ character allows + specifying a specific commit to retrieve from a branch. The + use cases for this are somewhat similar to pulling a specific + git tag; one could e.g. script a system upgrade to a known-good + version, rather than the latest from the content provider. +

    Example

    $ ostree --repo=repo pull --depth=-1 --mirror remote_name

    Perform a complete mirror of the remote. (This is + likely most useful if your repository is also + archive mode)

    $ ostree --repo=repo pull remote_name exampleos/x86_64/standard

    Fetch the most recent commit to exampleos/x86_64/standard.

    $ ostree --repo=repo pull remote_name exampleos/x86_64/standard@98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4

    Download the specific commit starting with + 98ea6e as if it was the latest commit for + exampleos/x86_64/standard.

    diff --git a/man/ostree-refs.html b/man/ostree-refs.html new file mode 100644 index 0000000000..2f51e81efa --- /dev/null +++ b/man/ostree-refs.html @@ -0,0 +1,36 @@ +ostree refs

    Name

    ostree-refs — List refs

    Synopsis

    ostree refs [OPTIONS...] [PREFIX]

    ostree refs {EXISTING} {--create=NEWREF}

    Description

    + Lists all refs available on the host. If specified, PREFIX assigns the refspec prefix; default + prefix is null, which lists all refs. This command can also be used to create or delete refs. +

    Options

    --list

    For historical reasons, refs + without this option will strip the specified prefix + from the output. Normally, one wants to see the full + ref, so providing this option ensures the refs are + printed in full, rather than + truncated.

    --create=NEWREF

    + Create a ref pointing to the commit EXISTING. NEWREF must not already exist, and EXISTING + must be an existing commit. More than one ref can point to the same commit. +

    --delete

    + Delete refs which match PREFIX, rather than listing them. If you are trying to reclaim space, + you will then need to ostree prune or ostree admin cleanup. +

    --revision, -r

    + When listing refs, also print their revisions. The revisions + will be separated by a tab character. +

    --alias, -A

    + If used with --create, create an alias. Otherwise just list aliases. +

    --collections, -c

    + Enable interactions with refs using the combination of their + collection IDs and ref names. When listing refs, this changes + the output format to include collection IDs, and enables + listing remote mirrored refs.

    When creating refs, the refspec value passed to the + --create option is treated as + COLLECTION-ID:REF-NAME and a mirrored ref + is created. (This is an abuse of the refspec syntax.)

    When deleting refs, all refs whose collection ID equals + PREFIX are deleted. +

    --force

    + When creating NEWREF with + --create, allow an existing ref to be + updated instead of erroring. +

    Example

    $ ostree refs

    +        my-branch
    +        gnome-ostree/buildmain/x86_64-runtime
    +
    diff --git a/man/ostree-remote.html b/man/ostree-remote.html new file mode 100644 index 0000000000..28e4edafef --- /dev/null +++ b/man/ostree-remote.html @@ -0,0 +1,60 @@ +ostree remote

    Name

    ostree-remote — Control remote repository configuration

    Synopsis

    ostree remote add [OPTIONS...] {NAME} {URL} [BRANCH...]

    ostree remote delete {NAME}

    ostree remote show-url {NAME}

    ostree remote list [OPTIONS...] {NAME}

    ostree remote gpg-import [OPTIONS...] {NAME} [KEY-ID...]

    ostree remote gpg-list-keys {NAME}

    ostree remote refs {NAME}

    ostree remote summary [OPTIONS...] {NAME}

    ostree remote add-cookie {NAME} {DOMAIN} {PATH} {COOKIE_NAME} {VALUE}

    ostree remote delete-cookie {NAME} {DOMAIN} {PATH} {COOKIE_NAME} {VALUE}

    ostree remote list-cookies {NAME}

    Description

    + Changes remote repository configurations. The NAME refers to the name of the remote. +

    + The BRANCH arguments to the + add subcommand specifies the configured branches + for the remote. See the branches section in + ostree.repo-config(5) + for more information. +

    + The gpg-import subcommand can associate GPG + keys to a specific remote repository for use when pulling signed + commits from that repository (if GPG verification is enabled). The + gpg-list-keys subcommand can be used to see the + GPG keys currently associated with a remote repository. +

    + The GPG keys to import may be in binary OpenPGP format or ASCII armored. The optional [KEY-ID] list can restrict which keys are imported from a keyring file or input stream. All keys are imported if this list is omitted. If neither --keyring nor --stdin options are given, then keys are imported from the user's personal GPG keyring. +

    + The various cookie related command allow management of a remote specific cookie jar. +

    'Add' Options

    --set="KEY=VALUE"

    + Set config option KEY=VALUE for remote. +

    --if-not-exists

    + Do nothing if the provided remote exists. +

    --force

    + Replace the provided remote if it exists. +

    --no-gpg-verify

    + Disable GPG verification. +

    --gpg-import=FILE

    + Import one or more GPG keys from a file. +

    + Equivalent to + ostree remote gpg-import --keyring=FILE. +

    --collection-id=COLLECTION-ID

    + Set the collection ID for the remote to a value provided by + the repository owner, which allows refs from this remote to be + shared peer to peer. +

    'List' Options

    -u, --show-urls

    + Show remote URLs in list +

    'Refs' Options

    --revision, -r

    + Also print the revisions for each ref. The revisions will + be separated by a tab character. +

    --cache-dir=DIR

    + Use an alternate cache directory in DIR. +

    'GPG-Import' Options

    -k, --keyring=FILE

    + Import one or more keys from a file. +

    + This option may be repeated to import from multiple files, + but may not be used in combination with + --stdin. +

    --stdin

    + Import one or more keys from standard input. +

    + This option may not be used in combination with + --keyring. +

    'Summary' Options

    --cache-dir=DIR

    + Use an alternate cache directory in DIR. +

    --raw

    + Show raw variant data +

    Example

    $ ostree remote show-url local

    +        http://192.168.122.1/repo
    +
    diff --git a/man/ostree-reset.html b/man/ostree-reset.html new file mode 100644 index 0000000000..a38c2559d4 --- /dev/null +++ b/man/ostree-reset.html @@ -0,0 +1,15 @@ +ostree reset

    Name

    ostree-reset — Reset a ref to a previous commit

    Synopsis

    ostree reset {REF} {REF_TO_RESET_TO}

    Description

    + Given a commit, this command will reset the ref to a previous specified commit. +

    Example

    $ ostree log my-branch

    +        commit 67e382b11d213a402a5313e61cbc69dfd5ab93cb07
    +        Date:  2014-06-12 13:42:54 +0000
    +            This is the second commit
    +
    +        commit ce19c41036cc45e49b0cecf6b157523c2105c4de1c
    +        Date:  2014-06-12 11:20:08 +0000
    +            Initial commit
    +

    $ ostree reset my-branch my-branch^

    $ ostree log my-branch

    +        commit ce19c41036cc45e49b0cecf6b157523c2105c4de1c
    +        Date:  2014-06-12 11:20:08 +0000
    +            Initial commit
    +
    diff --git a/man/ostree-rev-parse.html b/man/ostree-rev-parse.html new file mode 100644 index 0000000000..53bd4a2f0e --- /dev/null +++ b/man/ostree-rev-parse.html @@ -0,0 +1,7 @@ +ostree rev-parse

    Name

    ostree-rev-parse — Output the target of a rev

    Synopsis

    ostree rev-parse {REV} {PATH}

    Options

    --single, -S

    + If the repository has exactly one commit, then print it; any other case will result in an error. +

    Description

    + Given a REV, outputs the checksum of the latest commit of that revision. +

    Example

    $ ostree rev-parse my-branch

    +        ce19c41036cc45e49b0cecf6b157523c2105c4de1ce30101def1f759daafcc3e
    +
    diff --git a/man/ostree-show.html b/man/ostree-show.html new file mode 100644 index 0000000000..e1c6a6fbaa --- /dev/null +++ b/man/ostree-show.html @@ -0,0 +1,27 @@ +ostree show

    Name

    ostree-show — Output a metadata object

    Synopsis

    ostree show [OPTIONS...] {OBJECT}

    Description

    + Given an object, shows the metadata for that object. For a particular revision, it will show the data for the most recent commit to that revision. +

    Options

    --print-related

    + Show the "related" commits. +

    --print-variant-type="TYPE"

    + Memory map OBJECT (in this case a filename) to the GVariant type string. +

    --list-metadata-keys

    + List the available metadata keys. +

    --print-metadata-key="KEY"

    + Print string value of metadata key. +

    --list-detached-metadata-keys

    + List the available detached metadata keys. +

    --print-detached-metadata-key="KEY"

    + Print string value of detached metadata key. +

    --print-sizes

    + Show the commit size metadata. This in only supported for + commits that contain ostree.sizes + metadata. This can be included when creating commits with + ostree commit --generate-sizes. +

    --raw

    + Show raw variant data. +

    --gpg-homedir="HOMEDIR"

    + GPG home directory to use when looking for keyrings (if have GPGME - GNU Privacy Guard Made Easy). +

    Example

    $ ostree show my-branch

    +        commit 67e382b11d213a402a5313e61cbc69dfd5ab93cb07
    +        Date:  2014-06-12 13:42:54 +0000
    +
    diff --git a/man/ostree-sign.html b/man/ostree-sign.html new file mode 100644 index 0000000000..59b8d92f9d --- /dev/null +++ b/man/ostree-sign.html @@ -0,0 +1,35 @@ +ostree sign

    Name

    ostree-sign — Sign a commit

    Synopsis

    ostree sign [OPTIONS...] {COMMIT} {KEY-ID...}

    Description

    + Add a new signature to a commit. + + Note that currently, this will append a new signature even if + the commit is already signed with a given key. +

    + There are several "well-known" system places for `ed25519` trusted and revoked public keys -- expected single base64-encoded key per line. +

    Files: +

    • /etc/ostree/trusted.ed25519

    • /etc/ostree/revoked.ed25519

    • /usr/share/ostree/trusted.ed25519

    • /usr/share/ostree/revoked.ed25519

    +

    Directories containing files with keys: +

    • /etc/ostree/trusted.ed25519.d

    • /etc/ostree/revoked.ed25519.d

    • /usr/share/ostree/trusted.ed25519.d

    • /usr/share/ostree/rvokeded.ed25519.d

    +

    Options

    KEY-ID

    +

    for ed25519:

    + base64-encoded secret (for signing) or public key (for verifying). +

    for dummy:

    + ASCII-string used as secret key and public key. +

    +

    --verify

    + Verify signatures +

    -s, --sign-type

    + Use particular signature mechanism. Currently + available ed25519 and dummy + signature types. + + The default is ed25519 . +

    --keys-file

    + Read key(s) from file filename. +

    + Valid for ed25519 signature type. + For ed25519 this file must contain base64-encoded + secret key(s) (for signing) or public key(s) (for verifying) per line. +

    --keys-dir

    + Redefine the system path, where to search files and subdirectories with + well-known and revoked keys. +

    diff --git a/man/ostree-state-overlay@.service.html b/man/ostree-state-overlay@.service.html new file mode 100644 index 0000000000..d3a86be23b --- /dev/null +++ b/man/ostree-state-overlay@.service.html @@ -0,0 +1,35 @@ +ostree-state-overlay

    Name

    ostree-state-overlay@.service — Set up state overlays

    Synopsis

    ostree-state-overlay@.service

    Experimental

    + Note this feature is currently considered + experimental. It may not work correctly and some of its + semantics may be subject to change. Positive or negative feedback are both + welcome and may be provided at + https://github.com/ostreedev/ostree/discussions. If using + the feature via rpm-ostree, feedback may also be provided at + https://github.com/coreos/rpm-ostree/issues/233. +

    Description

    + In some cases, it's useful to be able to have a directory as part of the + OSTree commit yet still have this directory be writable client-side. One + example is software that ships in /opt. + /opt is its own vendor-namespaced alternate file + hierarchy which may contain both code and state. With state overlays, it's + possible to have the code part baked in the OSTree, but still allowing the + directory to be writable so that state can be kept there. +

    + Since it's writable, nothing prevents sufficiently privileged code to + modify or delete content that comes from the OSTree commit. This is in + sharp contrast with content in /usr, and more + closely matches a package manager-based distro. +

    + Crucially, this state is automatically rebased during upgrades (or more + generally, anytime a different OSTree commit is booted). The semantics + of the rebase are as follows: any state file or directory that modified + OSTree content is deleted, otherwise it is kept and merged onto the new + base content (using overlayfs). This mostly matches the semantics of a + package manager. +

    + To enable this feature, simply instantiate the unit template, using the + target path (in escaped systemd path notation) as the instance name. For + example, to enable it on /opt: +


    +$systemctlenable--nowostree-state-overlay@opt.service
    +

    diff --git a/man/ostree-static-delta.html b/man/ostree-static-delta.html new file mode 100644 index 0000000000..914e0c356a --- /dev/null +++ b/man/ostree-static-delta.html @@ -0,0 +1,68 @@ +ostree static-delta

    Name

    ostree-static-delta — Manage static delta files

    Synopsis

    ostree static-delta list

    ostree static-delta show

    ostree static-delta delete

    ostree static-delta generate {--to=REV} [OPTIONS...]

    ostree static-delta apply-offline [OPTIONS...] {PATH} [KEY-ID...]

    ostree static-delta verify [OPTIONS...] {STATIC-DELTA} [KEY-ID...]

    Description

    + List and manipulate static delta files. +

    'Generate' Options

    --from="REV"

    + Create delta from revision REV. +

    --to="REV"

    + Create delta to revision REV. (This option is required.) + The delta is from the parent of REV, unless specified otherwise by --from + or --empty. +

    --empty

    + Create delta from scratch. +

    --max-usize=SIZE

    + Maximum uncompressed size in megabytes. +

    --sign-type=ENGINE

    + Use particular signature engine. Currently + available ed25519 and dummy + signature types. + + The default is ed25519 . +

    --sign="KEY-ID"

    + There KEY-ID is: +

    for ed25519:

    + base64-encoded secret key for signing. +

    for dummy:

    + ASCII-string used as secret key. +

    +

    'Apply-offline' Options

    KEY-ID

    +

    for ed25519:

    + base64-encoded public key for verifying. +

    for dummy:

    + ASCII-string used as public key. +

    +

    --sign-type=ENGINE

    + Use particular signature engine. Currently + available ed25519 and dummy + signature types. +

    --keys-file

    + Read key(s) from file filename. +

    + Valid for ed25519 signature type. + For ed25519 this file must contain base64-encoded + public key(s) per line for verifying. +

    --keys-dir

    + Redefine the system path, where to search files and subdirectories with + well-known and revoked keys. +

    'Verify' Options

    KEY-ID

    +

    for ed25519:

    + base64-encoded public key for verifying. +

    for dummy:

    + ASCII-string used as public key. +

    +

    --sign-type=ENGINE

    + Use particular signature engine. Currently + available ed25519 and dummy + signature types. + + The default is ed25519 . +

    --keys-file

    + Read key(s) from file filename. +

    + Valid for ed25519 signature type. + For ed25519 this file must contain base64-encoded + public key(s) per line for verifying. +

    --keys-dir

    + Redefine the system path, where to search files and subdirectories with + well-known and revoked keys. +

    Example

    $ ostree static-delta

    +        (No static deltas)
    +
    diff --git a/man/ostree-summary.html b/man/ostree-summary.html new file mode 100644 index 0000000000..ef497f7c9b --- /dev/null +++ b/man/ostree-summary.html @@ -0,0 +1,52 @@ +ostree summary

    Name

    ostree-summary — Regenerate or view the summary metadata file

    Synopsis

    ostree summary [--gpg-sign=KEYID] [--gpg-homedir=HOMEDIR] [--sign=KEYID] [--sign-type=ENGINE] {--update} [--add-metadata=KEY=VALUE...]

    ostree summary { --view | --raw }

    Description

    + The summary file is an optional higher + level form of repository metadata that describes the + available branches. It needs to be manually regenerated after + a series of commits. Among other things, this allows atomically + updating multiple commits. +

    Options

    --update,-u

    + Update the summary file. This option can be combined + with --add-metadata to add metadata + fields to the summary. +

    If the repository has a collection ID configured, the + ostree-metadata branch for that collection ID + will also be updated with a new commit containing the given metadata, + which will be signed if the summary file is signed.

    --add-metadata,-m=KEY=VALUE

    + Specify an additional metadata field to add to the summary. + It must be in the format + KEY=VALUE + or as two separate arguments. The keys must be namespaced + for your organisation or repository using a dot prefix. The + values must be in GVariant text format. For example, + exampleos.end-of-life "@t 1445385600". + This option can be used multiple times. +

    --view,-v

    + View the contents of the summary file in a human readable format. +

    --raw

    + View the raw bytes of the summary file. +

    --gpg-sign=KEYID

    + GPG Key ID to sign the summary with. +

    --gpg-homedir=HOMEDIR

    + GPG Homedir to use when looking for keyrings. +

    --sign-type=ENGINE

    + Use particular signature engine. Currently + available ed25519 and dummy + signature types. + + The default is ed25519 . +

    --sign="KEY-ID"

    + There KEY-ID is: +

    for ed25519:

    + base64-encoded secret key for commit signing. +

    for dummy:

    + ASCII-string used as secret key. +

    +

    Examples

    $ ostree summary -u

    $ ostree summary -u -m key="'value'"

    $ ostree summary -v

    +* ostree/1/1/0
    +    Latest Commit (4.2 MB):
    +      9828ab80f357459b4ab50f0629beab2ae3b67318fc3d161d10a89fae353afa90
    +    Timestamp (ostree.commit.timestamp): 2017-11-21T01:41:10-08
    +    Version (ostree.commit.version): 1.2.3
    +
    +Last-Modified (ostree.summary.last-modified): 2018-01-12T22:06:38-08
    +
    diff --git a/man/ostree.html b/man/ostree.html new file mode 100644 index 0000000000..cf185d5c1d --- /dev/null +++ b/man/ostree.html @@ -0,0 +1,194 @@ +ostree

    Name

    ostree — Manage multiple bootable versioned filesystem trees

    Synopsis

    ostree {COMMAND} [OPTIONS...]

    Description

    + OSTree is a tool for managing multiple bootable + versioned filesystem trees, or just "tree" for + short. In the OSTree model, operating systems no + longer live in the physical "/" root directory. + Instead, they parallel install to the new toplevel + /ostree directory. Each + installed system gets its own + /ostree/deploy/stateroot + directory. (stateroot is the + newer term for osname). +

    + Unlike rpm or + dpkg, OSTree is only aware of + complete filesystem trees. It has no built-in + knowledge of what components went into creating the + filesystem tree. +

    + It is possible to use OSTree in several modes; the + most basic form is to replicate pre-built trees from + a build server. Usually, these pre-built trees are + derived from packages. You might also be using + OSTree underneath a higher level tool which computes + filesystem trees locally. +

    + It must be emphasized that OSTree only supports + read-only trees. To change to + a different tree (upgrade, downgrade, install + software), a new tree is checked out, and a 3-way + merge of configuration is performed. The currently + running tree is not ever modified; the new tree will + become active on a system reboot. +

    + To see the man page for a command run man ostree COMMAND or man ostree-admin COMMAND +

    Options

    The following options are understood:

    --repo

    + For most commands, a repository is + required. If unspecified, the current + directory is used if it appears to be an + OSTree repository. If it isn't, either + the OSTREE_REPO + environment variable is used, or the + system repository located at + /sysroot/ostree/repo. +

    -v, --verbose

    + Produce debug level output. +

    --version

    + Print version information, including the features enabled + at compile time, and exit. +

    Commands

    System administrators will primarily interact + with OSTree via the subcommand ostree + admin.

    ostree-admin-cleanup(1)

    + Delete untagged + deployments and repository objects. +

    ostree-admin-config-diff(1)

    + See changes to + /etc as compared + to the current default (from + /usr/etc). +

    ostree-admin-deploy(1)

    + Takes a particular + commit or revision, and sets it up for + the next boot. +

    ostree-admin-init-fs(1)

    + Initialize a root filesystem + in a specified path. +

    ostree-admin-instutil(1)

    + Utility functions intended primarily for operating system installation programs +

    ostree-admin-os-init(1)

    + Initialize the + deployment location for an operating + system with a specified name. +

    ostree-admin-status(1)

    + Show and list the deployments. +

    ostree-admin-switch(1)

    + Choose a different ref + to track from the same remote as the + current tree. +

    ostree-admin-undeploy(1)

    + Remove the previously + INDEX + deployed tree from the bootloader + configuration. +

    ostree-admin-upgrade(1)

    + Download the latest version for the + current ref, and deploy it. +

    Both administrators and operating system + builders may interact with OSTree via the regular + filesystem manipulation commands. +

    ostree-cat(1)

    + Concatenate contents of files +

    ostree-checkout(1)

    + Check out a commit into a filesystem tree. +

    ostree-checksum(1)

    + Gives checksum of any file. +

    ostree-commit(1)

    + Given one or more + trees, create a new commit using those contents. +

    ostree-config(1)

    + Change settings. +

    ostree-create-usb(1)

    + Put the given refs on an external drive for P2P distribution. +

    ostree-diff(1)

    + Concisely list + differences between the given refs. +

    ostree-find-remotes(1)

    + Find remotes to serve the given refs. +

    ostree-fsck(1)

    + Check a repository for consistency. +

    ostree-init(1)

    + Initialize a new repository. +

    ostree-log(1)

    + Show revision log. +

    ostree-ls(1)

    + List the contents of a given commit. +

    ostree-prune(1)

    + Search for unreachable objects. +

    ostree-pull-local(1)

    + Copy data from source-repo. +

    ostree-pull(1)

    + Download data from remote repo. If you have libsoup. +

    ostree-refs(1)

    + List refs. +

    ostree-remote(1)

    + Manipulate remote archive configuration. +

    ostree-reset(1)

    + Reset a ref to a previous commit. +

    ostree-rev-parse(1)

    + Show the SHA256 corresponding to a given rev. +

    ostree-show(1)

    + Given an OSTree SHA256 checksum, display its contents. +

    ostree-static-delta(1)

    + Manage static delta files. +

    ostree-summary(1)

    + Regenerate the repository summary metadata. +

    Examples

    + For specific examples, please see the man page regarding the specific ostree command. For example: +

    + man ostree init or man ostree-admin status +

    GPG verification

    + OSTree supports signing commits with GPG. Operations on the system + repository by default use keyring files in + /usr/share/ostree/trusted.gpg.d. Any + public key in a keyring file in that directory will be + trusted by the client. No private keys should be present + in this directory. +

    + In addition to the system repository, OSTree supports two + other paths. First, there is a + gpgkeypath option for remotes, which must point + to the filename of an ASCII-armored GPG key, or a directory containing + ASCII-armored GPG keys to import. Multiple file and directory paths + to import from can be specified, as a comma-separated list of paths. This option + may be specified by using --set in ostree remote add. +

    + Second, there is support for a per-remote + remotename.trustedkeys.gpg + file stored in the toplevel of the repository (alongside + objects/ and such). This is + particularly useful when downloading content that may not + be fully trusted (e.g. you want to inspect it but not + deploy it as an OS), or use it for containers. This file + is written via ostree remote add + --gpg-import. +

    Terminology

    + The following terms are commonly used throughout the man pages. Terms in upper case letters + are literals used in command line arguments. +

    BRANCH

    + Branch name. Part of a REF. +

    CHECKSUM

    + A SHA256 hash of a object stored in the OSTree repository. This can be a content, + a dirtree, a dirmeta or a commit object. If the SHA256 hash of a commit object is + meant, the term COMMIT is used. +

    COMMIT

    + A SHA256 hash of a commit object. +

    REF

    + A reference to a particular commit. References are text files stored in + refs/ that name (refer to) a particular commit. A + reference can only be the branch name part, in which case a local reference + is used (e.g. mybranch/stable). If a remote branch + is referred to, the remote name followed by a colon and the branch name + needs to be used (e.g. myremote:mybranch/stable). +

    REV, REFSPEC

    + A specific revision, a commit. This can be anything which can be resolved to a + commit, e.g. a REF or a + COMMIT. +

    SHA256

    + A cryptographic hash function used to store objects in the OSTree + repository. The hashes have a length of 256 bites and are typically + shown and passed to ostree in its 64 ASCII character long hexadecimal + representation + (e.g. 0fc70ed33cfd7d26fe99ae29afb7682ddd0e2157a4898bd8cfcdc8a03565b870). +

    See Also

    + ostree.repo(5) +

    diff --git a/man/ostree.repo-config.html b/man/ostree.repo-config.html new file mode 100644 index 0000000000..adf7690d0a --- /dev/null +++ b/man/ostree.repo-config.html @@ -0,0 +1,219 @@ +ostree.repo-config

    Name

    ostree.repo-config — OSTree repository configuration

    Description

    + The config file in an OSTree + repository is a "keyfile" in the XDG + Desktop Entry Specification format. It has + several global flags, as well as zero or more remote + entries which describe how to access remote + repositories. +

    + See ostree.repo(5) for more information + about OSTree repositories. +

    [core] Section Options

    + Repository-global options. The following entries are defined: +

    mode

    One of bare, bare-user, bare-user-only, or archive-z2 (note that archive is used everywhere else.)

    repo_version

    Currently, this must be set to 1.

    auto-update-summary

    Boolean value controlling whether or not to + automatically update the summary file after any ref is added, + removed, or updated. Other modifications which may render a + summary file stale (like static deltas, or collection IDs) do + not currently trigger an auto-update. +

    commit-update-summary

    This option is deprecated. Use + auto-update-summary instead, for which this + option is now an alias.

    fsync

    Boolean value controlling whether or not to + ensure files are on stable storage when performing operations + such as commits, pulls, and checkouts. Defaults to + true.

    + If you disable fsync, OSTree will no longer be robust + against kernel crashes or power loss. +

    + You might choose to disable this for local development + repositories, under the assumption they can be recreated from + source. Similarly, you could disable for a mirror where you could + re-pull. +

    + For the system repository, you might choose to disable fsync + if you have uninterruptable power supplies and a well tested + kernel. +

    per-object-fsync

    By default, OSTree will batch fsync() after + writing everything; however, this can cause latency spikes + for other processes which are also invoking fsync(). + Turn on this boolean to reduce potential latency spikes, + at the cost of slowing down OSTree updates. You most + likely want this on by default for "background" OS updates. +

    min-free-space-percent

    + Integer percentage value (0-99) that specifies a minimum percentage + of total space (in blocks) in the underlying filesystem to keep + free. The default value is 3, which is enforced when neither this + option nor min-free-space-size are set. +

    + If min-free-space-size is set to a non-zero + value, min-free-space-percent is ignored. Note + that, min-free-space-percent is not enforced on + metadata objects. It is assumed that metadata objects are relatively + small in size compared to content objects and thus kept outside the + scope of this option. +

    min-free-space-size

    + Value (in power-of-2 MB, GB or TB) that specifies a minimum space + in the underlying filesystem to keep free. Examples of acceptable + values: 500MB (524288000 bytes), + 1GB (1073741824 bytes), + 1TB (1099511627776 bytes). +

    + If this option is set to a non-zero value, and + min-free-space-percent is also set, this option + takes priority. Note that, min-free-space-size is + not enforced on metadata objects. It is assumed that metadata objects + are relatively small in size compared to content objects and thus kept + outside the scope of this option. +

    add-remotes-config-dir

    + Boolean value controlling whether new remotes will be added + in the remotes configuration directory. Defaults to + true for system ostree repositories. When + this is false, remotes will be added in + the repository's config file. +

    + This only applies to repositories that use a remotes + configuration directory such as system ostree repositories, + which use /etc/ostree/remotes.d. + Non-system repositories do not use a remotes configuration + directory unless one is specified when the repository is + opened. +

    payload-link-threshold

    An integer value that specifies a minimum file size for creating + a payload link. By default it is disabled. +

    collection-id

    A reverse DNS domain name under your control, which enables peer + to peer distribution of refs in this repository. See the + --collection-id section in + ostree-init(1) +

    locking

    Boolean value controlling whether or not OSTree does + repository locking internally. This uses file locks and is + hence for multiple process exclusion (e.g. Flatpak and OSTree + writing to the same repository separately). This is enabled by + default since 2018.5. +

    lock-timeout-secs

    Integer value controlling the number of seconds to + block while attempting to acquire a lock (see above). A value + of -1 means block indefinitely. The default value is 300. This timeout + is now regarded as a mistake; because it's likely to cause flakes. + It's recommended to set it to -1, and have timeouts at a higher application + level if desired. +

    default-repo-finders

    Semicolon separated default list of finders (sources + for refs) to use when pulling. This can be used to disable + pulling from mounted filesystems, peers on the local network, + or the Internet. However note that it only applies when a set + of finders isn't explicitly specified, either by a consumer of + libostree API or on the command line. Possible values: + config, lan, and + mount (or any combination thereof). If unset, this + defaults to config;mount; (since the LAN finder is + costly). +

    no-deltas-in-summary

    Boolean value controlling whether OSTree should skip + putting an index of available deltas in the summary file. Defaults to false. +

    + Since 2020.7 OSTree can use delta indexes outside the summary file, + making the summary file smaller (especially for larger repositories). However + by default we still create the index in the summary file to make older clients + work. If you know all clients will be 2020.7 later you can enable this to + save network bandwidth. +

    [remote "name"] Section Options

    + Describes a remote repository location. +

    url

    Must be present; declares URL for accessing metadata and + content for remote. See also contenturl. The + supported schemes are documented below.

    contenturl

    Declares URL for accessing content (filez, static delta + parts). When specified, url is used just for + metadata: summary, static delta "superblocks".

    branches

    A list of strings. Represents the default configured + branches to fetch from the remote when no specific branches are + requested during a pull operation.

    proxy

    A string value, if given should be a URL for a + HTTP proxy to use for access to this repository.

    gpg-verify

    A boolean value, defaults to true. + Controls whether or not OSTree will require commits to be + signed by a known GPG key. For more information, see the + ostree(1) + manual under GPG.

    gpg-verify-summary

    A boolean value, defaults to false. + Controls whether or not OSTree will check if the summary + is signed by a known GPG key. + For more information, see the ostree(1) + manual under GPG.

    tls-permissive

    A boolean value, defaults to false. By + default, server TLS certificates will be checked against the + system certificate store. If this variable is set, any + certificate will be accepted.

    tls-client-cert-path

    Path to file for client-side certificate, to present when making requests to this repository.

    tls-client-key-path

    Path to file containing client-side certificate key, to present when making requests to this repository.

    tls-ca-path

    Path to file containing trusted anchors instead of the system CA database.

    http2

    A boolean value, defaults to true. By + default, libostree will use HTTP2; setting this to false + will disable it. May be useful to work around broken servers. +

    unconfigured-state

    If set, pulls from this remote will fail with the configured text. This is intended for OS vendors which have a subscription process to access content.

    custom-backend

    If set, pulls from this remote via libostree will fail with an error that mentions the value. + It is recommended to make this a software identifier token (e.g. "examplecorp-fetcher"), not freeform text ("ExampleCorp Fetcher"). + This is intended to be used by higher level software that wants to fetch ostree commits via some other mechanism, while still reusing the core libostree infrastructure around e.g. signatures. +

    [sysroot] Section Options

    + Options for the sysroot, which contains the OSTree repository, + deployments, and stateroots. The following entries are defined: +

    readonly

    A boolean value. If this is set to true, then the + /sysroot mount point is mounted read-only. This is configured a + legacy repository configuration and the equivalent option in ostree/prepare-root.conf + should be used instead - see ostree-prepare-root(1). +

    bootloader

    Configure the bootloader that OSTree uses when + deploying the sysroot. This may take the values + bootloader=none, bootloader=auto, + bootloader=grub2, bootloader=syslinux, + bootloader=uboot or bootloader=zipl. + Default is auto. +

    + If none, then OSTree will generate only BLS (Boot + Loader Specification) fragments in sysroot/boot/loader/entries/ + for the deployment. +

    + If auto, then in addition to generating BLS + fragments, OSTree will dynamically check for the existence of grub2, + uboot, and syslinux bootloaders. If one of the bootloaders is found, + then OSTree will generate a config for the bootloader found. For + example, grub2-mkconfig is run for the grub2 case. +

    + A specific bootloader type may also be explicitly requested by choosing + grub2, syslinux, uboot or + zipl. +

    bls-append-except-default

    A semicolon separated string list of key-value pairs. For example: + bls-append-except-default=key1=value1;key2=value2. These key-value + pairs will be injected into the generated BLS fragments of the non-default deployments. + In other words, the BLS fragment of the default deployment will be unaffected by + bls-append-except-default. +

    bootprefix

    A boolean value; defaults to false. If set to true, the bootloader entries + generated will include /boot as a prefix. This will likely be turned + on by default in the future. +

    [ex-integrity] Section Options

    + The "ex-" prefix here signifies experimental options. The ex-integrity section + contains options related to system integrity. Information about experimental + options is canonically found in upstream tracking issues. +

    /etc/ostree/remotes.d

    + In addition to the /ostree/repo/config + file, remotes may also be specified in + /etc/ostree/remotes.d. The remote + configuration file must end in .conf; files + whose name does not end in .conf will be + ignored. +

    Repository url/contenturl

    + Originally, OSTree had just a url option + for remotes. Since then, the contenturl + option was introduced. Both of these support + file, http, and + https schemes. +

    + Additionally, both of these can be prefixed with the string + mirrorlist=, which instructs the client + that the target url is a "mirrorlist" format, which is + a plain text file of newline-separated URLs. Earlier + URLs will be given precedence. +

    + Note that currently, the tls-ca-path and + tls-client-cert-path options apply to every HTTP + request, even when contenturl and/or + mirrorlist are in use. This may change in the future to + only apply to metadata (i.e. url, not + contenturl) fetches. +

    Per-remote GPG keyrings and verification

    + OSTree supports a per-remote GPG keyring, as well as a + gpgkeypath option. For more information see + ostree(1). + in the section GPG verification. +

    Per-remote HTTP cookies

    + Some content providers may want to control access to remote + repositories via HTTP cookies. The ostree remote + add-cookie and ostree remote + delete-cookie commands will update a per-remote + lookaside cookie jar, named + $remotename.cookies.txt. +

    See Also

    + ostree(1), ostree.repo(5) +

    diff --git a/man/ostree.repo.html b/man/ostree.repo.html new file mode 100644 index 0000000000..5cf18a6835 --- /dev/null +++ b/man/ostree.repo.html @@ -0,0 +1,30 @@ +ostree.repo

    Name

    ostree.repo — OSTree repository configuration and layout

    Description

    + An OSTree repository is structurally similar to a + git repository; it is a content-addressed object + store containing filesystem trees. However, unlike + git, ostree is designed to store operating system + binaries. It records the Unix uid and gid, + permissions, as well as extended attributes. +

    + A repository can be in one of three modes; + bare, which is designed as a hard + link source for operating system checkouts, + bare-user, which is like + bare but works on systems that + run as non-root as well as non-root containers, and + archive-z2, which is designed for + static HTTP servers. +

    + There is a system repository located at + /ostree/repo. If no repository + is specified -- either by a command-line option or the + OSTREE_REPO environment variable -- + the ostree as well as many API + calls will use it by default. +

    Components of a repository

    + The only user-editable component is the + config file. For more + information, see ostree.repo-config(5). +

    diff --git a/man/rofiles-fuse.html b/man/rofiles-fuse.html new file mode 100644 index 0000000000..b9b46ace03 --- /dev/null +++ b/man/rofiles-fuse.html @@ -0,0 +1,31 @@ +rofiles-fuse

    Name

    rofiles-fuse — Use FUSE to create a view where directories are writable, files are immutable

    Synopsis

    rofiles-fuse SRCDIR MNTPOINT

    Description

    + Creating a checkout from an OSTree repository by default + uses hard links, which means an in-place mutation to any + file corrupts the repository and all checkouts. This can be + problematic if one wishes to run arbitrary programs against + such a checkout. For example, RPM %post + scripts or equivalent. +

    + In the case where one wants to create a tree commit derived + from other content, using rofiles-fuse in + concert with ostree commit + --link-checkout-speedup (or the underlying API) + can ensure that only new files are checksummed. +

    Example: Update an OSTree commit

    +# Initialize a checkout and mount
    +$ ostree --repo=repo checkout somebranch branch-checkout
    +$ mkdir mnt
    +$ rofiles-fuse branch-checkout mnt
    +
    +# Now, arbitrary changes to mnt/ are reflected in branch-checkout
    +$ echo somenewcontent > mnt/anewfile
    +$ mkdir mnt/anewdir
    +$ rm mnt/someoriginalcontent -rf
    +
    +# Commit and cleanup
    +$ fusermount -u mnt
    +$ ostree --repo=repo commit --link-checkout-speedup -b somebranch -s 'Commit new content' --tree=dir=branch-checkout
    +$ rm mnt branch-checkout -rf
    +	

    See Also

    + ostree(1) +

    diff --git a/reference/home.png b/reference/home.png new file mode 100644 index 0000000000000000000000000000000000000000..9346b336a784463192c7daab5133a3673dd69845 GIT binary patch literal 256 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefRMbARQqaxysz9Q}BI-m)~Y zggoA|1V*z2{cQ=d;!=?fvu4~`n82RKrk1UubNXTJj1GP|o-=>$A29f{JgJ9K`^t{Q z-oWs>M&_hvT&MjX@T4-&sBW+1^4oB5G4r2q!qGktZ!n*!)hjrjd0_4L6;4%u<}orJ u%Vo~x?#i!!ww+1OGuHe}T=cKQUzn^_t)8|WlnDbmjKR~@&t;ucLK6T + + + +OSTree API references: OSTree API references + + + + + + + +
    +
    +
    +
    +

    for OSTree 2024.6

    +
    +
    +
    +
    +
    API Reference
    +
    +
    +Core repository-independent functions — Create, validate, and convert core data types +
    +
    +OstreeRepo: Content-addressed object store — A git-like storage system for operating system binaries +
    +
    +In-memory modifiable filesystem tree — Modifiable filesystem tree +
    +
    +Root partition mount point — Manage physical root filesystem +
    +
    +Progress notification system for asynchronous operations — Values representing progress +
    +
    +SELinux policy management — Read SELinux policy and manage filesystem labels +
    +
    +Simple upgrade class — Upgrade OSTree systems +
    +
    +GPG signature verification results — Inspect detached GPG signatures +
    +
    +Signature management — Sign and verify commits +
    +
    +ostree-bootconfig-parser +
    +
    +ostree-chain-input-stream +
    +
    +ostree-checksum-input-stream +
    +
    +ostree-content-writer +
    +
    +ostree-deployment +
    +
    +ostree-diff +
    +
    +ostree-kernel-args +
    +
    +ostree-ref +
    +
    +ostree-remote +
    +
    +ostree-repo-file +
    +
    +ostree-repo-finder +
    +
    +ostree-repo-remote-finder +
    +
    +ostree-version — ostree version checking +
    +
    API Index
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/left-insensitive.png b/reference/left-insensitive.png new file mode 100644 index 0000000000000000000000000000000000000000..3269393a7f72af744a772c437bd7b3976c23709d GIT binary patch literal 395 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefH0HbvDJm`3=E7Co-U3d7N^fnTIWJ3j{^~q!iyia4kV=mdU|Jhfgdm;SLIpiYJ7wv^kjFiECCc&8T30!RG0~&BG=X zlu#U4@Z`))V`EG9e^NqDr#{!5k|)wT* zYTNt0`@q%TAD$){%#eQ?;$^ly8}yZCU%T~u0XM^%t?f#e znB*EuLv2rP%K3BMvFO}YmnR}KSgH;`EHL$)^!tH~iBxZ#h^zJi*#P5Xb6B50U@nx2 mU;T=yfcwnSOsS9SKd{M#MlNkCuvG>I8-u5-pUXO@geCx5`k@p6 literal 0 HcmV?d00001 diff --git a/reference/left.png b/reference/left.png new file mode 100644 index 0000000000000000000000000000000000000000..2abde032b0c98b756b12d380da4318205cd78470 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjTefRMaSLay~*pwMJb7sn8b(^oI8=R24v(*CjE{-BFv z0BhvLm?o9(UC{-Ci?lD?Ve-7-xypA!PTC(0^;>UheG4Altep3@`rO0#Rjs1)RxCLr zE5mee>7m*=%yEk+GVvGkRy0O&*&MTd5SjH(lgq~7r%6oRW$l1p-*S}iC>@fyDsz%y z`UIW8^Ao=maGhj3E8{7Cd_qof`K4oa->23`>&M2+XBtd2J`8jogQu&X%Q~loCIG_? BVG#fT literal 0 HcmV?d00001 diff --git a/reference/ostree-Core-repository-independent-functions.html b/reference/ostree-Core-repository-independent-functions.html new file mode 100644 index 0000000000..ec7684fdcc --- /dev/null +++ b/reference/ostree-Core-repository-independent-functions.html @@ -0,0 +1,3058 @@ + + + + +Core repository-independent functions: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Core repository-independent functions

    +

    Core repository-independent functions — Create, validate, and convert core data types

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #define +OSTREE_OBJECT_TYPE_IS_META() +
    const GVariantType * + +ostree_metadata_variant_type () +
    +gboolean + +ostree_validate_checksum_string () +
    +gboolean + +ostree_validate_collection_id () +
    +guchar * + +ostree_checksum_to_bytes () +
    +GVariant * + +ostree_checksum_to_bytes_v () +
    +char * + +ostree_checksum_from_bytes () +
    +char * + +ostree_checksum_from_bytes_v () +
    +void + +ostree_checksum_inplace_from_bytes () +
    +void + +ostree_checksum_inplace_to_bytes () +
    const guchar * + +ostree_checksum_bytes_peek () +
    const guchar * + +ostree_checksum_bytes_peek_validate () +
    +char * + +ostree_checksum_b64_from_bytes () +
    +guchar * + +ostree_checksum_b64_to_bytes () +
    +void + +ostree_checksum_b64_inplace_from_bytes () +
    +void + +ostree_checksum_b64_inplace_to_bytes () +
    +int + +ostree_cmp_checksum_bytes () +
    +gboolean + +ostree_validate_rev () +
    +gboolean + +ostree_validate_remote_name () +
    +gboolean + +ostree_parse_refspec () +
    const char * + +ostree_object_type_to_string () +
    +OstreeObjectType + +ostree_object_type_from_string () +
    +guint + +ostree_hash_object_name () +
    +GVariant * + +ostree_object_name_serialize () +
    +void + +ostree_object_name_deserialize () +
    +char * + +ostree_object_to_string () +
    +void + +ostree_object_from_string () +
    +gboolean + +ostree_content_stream_parse () +
    +gboolean + +ostree_content_file_parse () +
    +gboolean + +ostree_content_file_parse_at () +
    +gboolean + +ostree_raw_file_to_archive_z2_stream () +
    +gboolean + +ostree_raw_file_to_archive_z2_stream_with_options () +
    +gboolean + +ostree_raw_file_to_content_stream () +
    +gboolean + +ostree_break_hardlink () +
    +gboolean + +ostree_checksum_file_from_input () +
    +gboolean + +ostree_checksum_file () +
    +gboolean + +ostree_checksum_file_at () +
    +void + +ostree_checksum_file_async () +
    +gboolean + +ostree_checksum_file_async_finish () +
    +GVariant * + +ostree_fs_get_all_xattrs () +
    +GVariant * + +ostree_fs_get_all_xattrs_at () +
    +GVariant * + +ostree_create_directory_metadata () +
    +gboolean + +ostree_validate_structureof_objtype () +
    +gboolean + +ostree_validate_structureof_csum_v () +
    +gboolean + +ostree_validate_structureof_checksum_string () +
    +gboolean + +ostree_validate_structureof_file_mode () +
    +gboolean + +ostree_validate_structureof_commit () +
    +gboolean + +ostree_validate_structureof_dirtree () +
    +gboolean + +ostree_validate_structureof_dirmeta () +
    +gchar * + +ostree_commit_get_parent () +
    +guint64 + +ostree_commit_get_timestamp () +
    +gboolean + +ostree_commit_metadata_for_bootable () +
    +gchar * + +ostree_commit_get_content_checksum () +
    +gboolean + +ostree_commit_get_object_sizes () +
    +OstreeCommitSizesEntry * + +ostree_commit_sizes_entry_new () +
    +OstreeCommitSizesEntry * + +ostree_commit_sizes_entry_copy () +
    +void + +ostree_commit_sizes_entry_free () +
    +gboolean + +ostree_check_version () +
    +
    + +
    +

    Description

    +

    These functions implement repository-independent algorithms for +operating on the core OSTree data formats, such as converting +GFileInfo into a GVariant.

    +

    There are 4 types of objects; file, dirmeta, tree, and commit. The +last 3 are metadata, and the file object is the only content object +type.

    +

    All metadata objects are stored as GVariant (big endian). The +rationale for this is the same as that of the ext{2,3,4} family of +filesystems; most developers will be using LE, and so it's better +to continually test the BE->LE swap.

    +

    The file object is a custom format in order to support streaming.

    +
    +
    +

    Functions

    +
    +

    OSTREE_OBJECT_TYPE_IS_META()

    +
    #define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 6)
    +
    +
    +

    Parameters

    +
    +++++ + + + + + +

    t

    An OstreeObjectType

     
    +
    +
    +

    Returns

    +

    TRUE if object type is metadata

    +
    +
    +
    +
    +

    ostree_metadata_variant_type ()

    +
    const GVariantType *
    +ostree_metadata_variant_type (OstreeObjectType objtype);
    +
    +
    +
    +

    ostree_validate_checksum_string ()

    +
    gboolean
    +ostree_validate_checksum_string (const char *sha256,
    +                                 GError **error);
    +

    Use this function to see if input strings are checksums.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    sha256

    SHA256 hex string

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if sha256 +is a valid checksum string, FALSE otherwise

    +
    +
    +
    +
    +

    ostree_validate_collection_id ()

    +
    gboolean
    +ostree_validate_collection_id (const char *collection_id,
    +                               GError **error);
    +

    Check whether the given collection_id + is valid. Return an error if it is +invalid or NULL.

    +

    Valid collection IDs are reverse DNS names:

    +
      +
    • They are composed of 1 or more elements separated by a period (.) character. +All elements must contain at least one character.

    • +
    • Each element must only contain the ASCII characters [A-Z][a-z][0-9]_ and must not +begin with a digit.

    • +
    • They must contain at least one . (period) character (and thus at least two elements).

    • +
    • They must not begin with a . (period) character.

    • +
    • They must not exceed 255 characters in length.

    • +
    +

    (This makes their format identical to D-Bus interface names, for consistency.)

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    collection_id

    A collection ID.

    [nullable]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if collection_id +is a valid collection ID, FALSE if it is invalid +or NULL

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_checksum_to_bytes ()

    +
    guchar *
    +ostree_checksum_to_bytes (const char *checksum);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    checksum

    An ASCII checksum

     
    +
    +
    +

    Returns

    +

    Binary checksum from checksum +of length 32; +free with g_free().

    +

    [transfer full][array fixed-size=32]

    +
    +
    +
    +
    +

    ostree_checksum_to_bytes_v ()

    +
    GVariant *
    +ostree_checksum_to_bytes_v (const char *checksum);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    checksum

    An ASCII checksum

     
    +
    +
    +

    Returns

    +

    New GVariant of type ay with length 32.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_checksum_from_bytes ()

    +
    char *
    +ostree_checksum_from_bytes (const guchar *csum);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    csum

    An binary checksum of length 32.

    [array fixed-size=32]
    +
    +
    +

    Returns

    +

    String form of csum +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_checksum_from_bytes_v ()

    +
    char *
    +ostree_checksum_from_bytes_v (GVariant *csum_v);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    csum_v

    GVariant of type ay

     
    +
    +
    +

    Returns

    +

    String form of csum_bytes +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_checksum_inplace_from_bytes ()

    +
    void
    +ostree_checksum_inplace_from_bytes (const guchar *csum,
    +                                    char *buf);
    +

    Overwrite the contents of buf + with stringified version of csum +.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    csum

    An binary checksum of length 32.

    [array fixed-size=32]

    buf

    Output location, must be at least OSTREE_SHA256_STRING_LEN+1 bytes in length

     
    +
    +
    +
    +
    +

    ostree_checksum_inplace_to_bytes ()

    +
    void
    +ostree_checksum_inplace_to_bytes (const char *checksum,
    +                                  guchar *buf);
    +

    Convert checksum + from a string to binary in-place, without +allocating memory. Use this function in hot code paths.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    a SHA256 string

     

    buf

    Output buffer with at least 32 bytes of space

     
    +
    +
    +
    +
    +

    ostree_checksum_bytes_peek ()

    +
    const guchar *
    +ostree_checksum_bytes_peek (GVariant *bytes);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    bytes

    GVariant of type ay

     
    +
    +
    +

    Returns

    +

    Binary checksum data in +bytes +; do not free. If bytes +does not have the correct length, return NULL.

    +

    [transfer none][array fixed-size=32][element-type guint8]

    +
    +
    +
    +
    +

    ostree_checksum_bytes_peek_validate ()

    +
    const guchar *
    +ostree_checksum_bytes_peek_validate (GVariant *bytes,
    +                                     GError **error);
    +

    Like ostree_checksum_bytes_peek(), but also throws error +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    bytes

    GVariant of type ay

     

    error

    Errror

     
    +
    +
    +

    Returns

    +

    Binary checksum data.

    +

    [transfer none][array fixed-size=32][element-type guint8]

    +
    +
    +
    +
    +

    ostree_checksum_b64_from_bytes ()

    +
    char *
    +ostree_checksum_b64_from_bytes (const guchar *csum);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    csum

    An binary checksum of length 32.

    [array fixed-size=32]
    +
    +
    +

    Returns

    +

    Modified base64 encoding of csum +

    +

    The "modified" term refers to the fact that instead of '/', the '_' +character is used.

    +

    [transfer full]

    +
    +

    Since: 2016.8

    +
    +
    +
    +

    ostree_checksum_b64_to_bytes ()

    +
    guchar *
    +ostree_checksum_b64_to_bytes (const char *checksum);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    checksum

    An ASCII checksum

     
    +
    +
    +

    Returns

    +

    Binary version of checksum +.

    +

    [transfer full][array fixed-size=32]

    +
    +

    Since: 2016.8

    +
    +
    +
    +

    ostree_checksum_b64_inplace_from_bytes ()

    +
    void
    +ostree_checksum_b64_inplace_from_bytes
    +                               (const guchar *csum,
    +                                char *buf);
    +

    Overwrite the contents of buf + with modified base64 encoding of csum +. +The "modified" term refers to the fact that instead of '/', the '_' +character is used.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    csum

    An binary checksum of length 32.

    [array fixed-size=32]

    buf

    Output location, must be at least 44 bytes in length

     
    +
    +
    +
    +
    +

    ostree_checksum_b64_inplace_to_bytes ()

    +
    void
    +ostree_checksum_b64_inplace_to_bytes (const char *checksum,
    +                                      guint8 *buf);
    +

    Overwrite the contents of buf + with stringified version of csum +.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    An binary checksum of length 32.

    [array fixed-size=32]

    buf

    Output location, must be at least 45 bytes in length

     
    +
    +
    +
    +
    +

    ostree_cmp_checksum_bytes ()

    +
    int
    +ostree_cmp_checksum_bytes (const guchar *a,
    +                           const guchar *b);
    +

    Compare two binary checksums, using memcmp().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    a

    A binary checksum

     

    b

    A binary checksum

     
    +
    +
    +
    +
    +

    ostree_validate_rev ()

    +
    gboolean
    +ostree_validate_rev (const char *rev,
    +                     GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    rev

    A revision string

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if rev +is a valid ref string

    +
    +
    +
    +
    +

    ostree_validate_remote_name ()

    +
    gboolean
    +ostree_validate_remote_name (const char *remote_name,
    +                             GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    remote_name

    A remote name

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if remote_name +is a valid remote name

    +
    +

    Since: 2017.8

    +
    +
    +
    +

    ostree_parse_refspec ()

    +
    gboolean
    +ostree_parse_refspec (const char *refspec,
    +                      char **out_remote,
    +                      char **out_ref,
    +                      GError **error);
    +

    Split a refspec like gnome-ostree:gnome-ostree/buildmain or just +gnome-ostree/buildmain into two parts. In the first case, out_remote + +will be set to gnome-ostree, and out_ref + to gnome-ostree/buildmain. +In the second case (a local ref), out_remote + will be NULL, and out_ref + +will be gnome-ostree/buildmain. In both cases, TRUE will be returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    refspec

    A "refspec" string

     

    out_remote

    Return location for the remote name, +or NULL if the refspec refs to a local ref.

    [out][nullable][optional]

    out_ref

    Return location for the ref name.

    [out][not nullable][optional]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on successful parsing, FALSE otherwise

    +
    +
    +
    +
    +

    ostree_object_type_to_string ()

    +
    const char *
    +ostree_object_type_to_string (OstreeObjectType objtype);
    +

    Serialize objtype + to a string; this is used for file extensions.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    objtype

    an OstreeObjectType

     
    +
    +
    +
    +
    +

    ostree_object_type_from_string ()

    +
    OstreeObjectType
    +ostree_object_type_from_string (const char *str);
    +

    The reverse of ostree_object_type_to_string().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    str

    A stringified version of OstreeObjectType

     
    +
    +
    +
    +
    +

    ostree_hash_object_name ()

    +
    guint
    +ostree_hash_object_name (gconstpointer a);
    +

    Use this function with GHashTable and ostree_object_name_serialize().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    a

    A GVariant containing a serialized object

     
    +
    +
    +
    +
    +

    ostree_object_name_serialize ()

    +
    GVariant *
    +ostree_object_name_serialize (const char *checksum,
    +                              OstreeObjectType objtype);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    An ASCII checksum

     

    objtype

    An object type

     
    +
    +
    +

    Returns

    +

    A new floating GVariant containing checksum string and objtype.

    +

    [transfer floating]

    +
    +
    +
    +
    +

    ostree_object_name_deserialize ()

    +
    void
    +ostree_object_name_deserialize (GVariant *variant,
    +                                const char **out_checksum,
    +                                OstreeObjectType *out_objtype);
    +

    Reverse ostree_object_name_serialize(). Note that out_checksum + is +only valid for the lifetime of variant +, and must not be freed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    variant

    A GVariant of type (su)

     

    out_checksum

    Pointer into string memory of variant +with checksum.

    [out][transfer none]

    out_objtype

    Return object type.

    [out]
    +
    +
    +
    +
    +

    ostree_object_to_string ()

    +
    char *
    +ostree_object_to_string (const char *checksum,
    +                         OstreeObjectType objtype);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    An ASCII checksum

     

    objtype

    Object type

     
    +
    +
    +

    Returns

    +

    A string containing both checksum +and a stringifed version of objtype +

    +
    +
    +
    +
    +

    ostree_object_from_string ()

    +
    void
    +ostree_object_from_string (const char *str,
    +                           gchar **out_checksum,
    +                           OstreeObjectType *out_objtype);
    +

    Reverse ostree_object_to_string().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    str

    An ASCII checksum

     

    out_checksum

    Parsed checksum.

    [out][transfer full]

    out_objtype

    Parsed object type.

    [out]
    +
    +
    +
    +
    +

    ostree_content_stream_parse ()

    +
    gboolean
    +ostree_content_stream_parse (gboolean compressed,
    +                             GInputStream *input,
    +                             guint64 input_length,
    +                             gboolean trusted,
    +                             GInputStream **out_input,
    +                             GFileInfo **out_file_info,
    +                             GVariant **out_xattrs,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +

    The reverse of ostree_raw_file_to_content_stream(); this function +converts an object content stream back into components.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    compressed

    Whether or not the stream is zlib-compressed

     

    input

    Object content stream

     

    input_length

    Length of stream

     

    trusted

    If TRUE, assume the content has been validated

     

    out_input

    The raw file content stream.

    [out]

    out_file_info

    Normal metadata.

    [out]

    out_xattrs

    Extended attributes.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_content_file_parse ()

    +
    gboolean
    +ostree_content_file_parse (gboolean compressed,
    +                           GFile *content_path,
    +                           gboolean trusted,
    +                           GInputStream **out_input,
    +                           GFileInfo **out_file_info,
    +                           GVariant **out_xattrs,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    A thin wrapper for ostree_content_stream_parse(); this function +converts an object content stream back into components.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    compressed

    Whether or not the stream is zlib-compressed

     

    content_path

    Path to file containing content

     

    trusted

    If TRUE, assume the content has been validated

     

    out_input

    The raw file content stream.

    [out]

    out_file_info

    Normal metadata.

    [out]

    out_xattrs

    Extended attributes.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_content_file_parse_at ()

    +
    gboolean
    +ostree_content_file_parse_at (gboolean compressed,
    +                              int parent_dfd,
    +                              const char *path,
    +                              gboolean trusted,
    +                              GInputStream **out_input,
    +                              GFileInfo **out_file_info,
    +                              GVariant **out_xattrs,
    +                              GCancellable *cancellable,
    +                              GError **error);
    +

    A thin wrapper for ostree_content_stream_parse(); this function +converts an object content stream back into components.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    compressed

    Whether or not the stream is zlib-compressed

     

    parent_dfd

    Directory file descriptor

     

    path

    Subpath

     

    trusted

    If TRUE, assume the content has been validated

     

    out_input

    The raw file content stream.

    [out]

    out_file_info

    Normal metadata.

    [out]

    out_xattrs

    Extended attributes.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_raw_file_to_archive_z2_stream ()

    +
    gboolean
    +ostree_raw_file_to_archive_z2_stream (GInputStream *input,
    +                                      GFileInfo *file_info,
    +                                      GVariant *xattrs,
    +                                      GInputStream **out_input,
    +                                      GCancellable *cancellable,
    +                                      GError **error);
    +

    Convert from a "bare" file representation into an +OSTREE_OBJECT_TYPE_FILE stream suitable for ostree pull.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    input

    File raw content stream

     

    file_info

    A file info

     

    xattrs

    Optional extended attributes.

    [allow-none]

    out_input

    Serialized object stream.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.6

    +
    +
    +
    +

    ostree_raw_file_to_archive_z2_stream_with_options ()

    +
    gboolean
    +ostree_raw_file_to_archive_z2_stream_with_options
    +                               (GInputStream *input,
    +                                GFileInfo *file_info,
    +                                GVariant *xattrs,
    +                                GVariant *options,
    +                                GInputStream **out_input,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Like ostree_raw_file_to_archive_z2_stream(), but supports an extensible set +of flags. The following flags are currently defined:

    +
    • compression-level (i): Level of compression to use, 0–9, with 0 being +the least compression, and <0 giving the default level (currently 6).

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    input

    File raw content stream

     

    file_info

    A file info

     

    xattrs

    Optional extended attributes.

    [allow-none]

    options

    A GVariant a{sv} with an extensible set of flags.

    [nullable]

    out_input

    Serialized object stream.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2017.3

    +
    +
    +
    +

    ostree_raw_file_to_content_stream ()

    +
    gboolean
    +ostree_raw_file_to_content_stream (GInputStream *input,
    +                                   GFileInfo *file_info,
    +                                   GVariant *xattrs,
    +                                   GInputStream **out_input,
    +                                   guint64 *out_length,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Convert from a "bare" file representation into an +OSTREE_OBJECT_TYPE_FILE stream. This is a fundamental operation +for writing data to an OstreeRepo.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    input

    File raw content stream

     

    file_info

    A file info

     

    xattrs

    Optional extended attributes.

    [allow-none]

    out_input

    Serialized object stream.

    [out]

    out_length

    Length of stream.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_break_hardlink ()

    +
    gboolean
    +ostree_break_hardlink (int dfd,
    +                       const char *path,
    +                       gboolean skip_xattrs,
    +                       GCancellable *cancellable,
    +                       GError **error);
    +

    In many cases using libostree, a program may need to "break" +hardlinks by performing a copy. For example, in order to +logically append to a file.

    +

    This function performs full copying, including e.g. extended +attributes and permissions of both regular files and symbolic links.

    +

    If the file is not hardlinked, this function does nothing and +returns successfully.

    +

    This function does not perform synchronization via fsync() or +fdatasync(); the idea is this will commonly be done as part +of an ostree_repo_commit_transaction(), which itself takes +care of synchronization.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    dfd

    Directory fd

     

    path

    Path relative to dfd +

     

    skip_xattrs

    Do not copy extended attributes

     

    error

    error

     
    +
    +

    Since: 2017.15

    +
    +
    +
    +

    ostree_checksum_file_from_input ()

    +
    gboolean
    +ostree_checksum_file_from_input (GFileInfo *file_info,
    +                                 GVariant *xattrs,
    +                                 GInputStream *in,
    +                                 OstreeObjectType objtype,
    +                                 guchar **out_csum,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Compute the OSTree checksum for a given input.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    file_info

    File information

     

    xattrs

    Optional extended attributes.

    [allow-none]

    in

    File content, should be NULL for symbolic links.

    [allow-none]

    objtype

    Object type

     

    out_csum

    Return location for binary checksum.

    [out][array fixed-size=32]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_checksum_file ()

    +
    gboolean
    +ostree_checksum_file (GFile *f,
    +                      OstreeObjectType objtype,
    +                      guchar **out_csum,
    +                      GCancellable *cancellable,
    +                      GError **error);
    +

    Compute the OSTree checksum for a given file.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    f

    File path

     

    objtype

    Object type

     

    out_csum

    Return location for binary checksum.

    [out][array fixed-size=32]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_checksum_file_at ()

    +
    gboolean
    +ostree_checksum_file_at (int dfd,
    +                         const char *path,
    +                         struct stat *stbuf,
    +                         OstreeObjectType objtype,
    +                         OstreeChecksumFlags flags,
    +                         char **out_checksum,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Compute the OSTree checksum for a given file. This is an fd-relative version +of ostree_checksum_file() which also takes flags and fills in a caller +allocated buffer.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    dfd

    Directory file descriptor

     

    path

    Subpath

     

    stbuf (allow-none)

    Optional stat buffer

     

    objtype

    Object type

     

    flags

    Flags

     

    out_checksum (out) (transfer full)

    Return location for hex checksum

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2017.13

    +
    +
    +
    +

    ostree_checksum_file_async ()

    +
    void
    +ostree_checksum_file_async (GFile *f,
    +                            OstreeObjectType objtype,
    +                            int io_priority,
    +                            GCancellable *cancellable,
    +                            GAsyncReadyCallback callback,
    +                            gpointer user_data);
    +

    Asynchronously compute the OSTree checksum for a given file; +complete with ostree_checksum_file_async_finish().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    f

    File path

     

    objtype

    Object type

     

    io_priority

    Priority for operation, see G_IO_PRIORITY_DEFAULT

     

    cancellable

    Cancellable

     

    callback

    Invoked when operation is complete

     

    user_data

    Data for callback +

     
    +
    +
    +
    +
    +

    ostree_checksum_file_async_finish ()

    +
    gboolean
    +ostree_checksum_file_async_finish (GFile *f,
    +                                   GAsyncResult *result,
    +                                   guchar **out_csum,
    +                                   GError **error);
    +

    Finish computing the OSTree checksum for a given file; see +ostree_checksum_file_async().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    f

    File path

     

    result

    Async result

     

    out_csum

    Return location for binary checksum.

    [out][array fixed-size=32]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_fs_get_all_xattrs ()

    +
    GVariant *
    +ostree_fs_get_all_xattrs (int fd,
    +                          GCancellable *cancellable,
    +                          GError **error);
    +

    Retrieve all extended attributes in a canonical (sorted) order from +the given file descriptor.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    fd

    File descriptor

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    A GVariant of type a(ayay).

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_fs_get_all_xattrs_at ()

    +
    GVariant *
    +ostree_fs_get_all_xattrs_at (int dfd,
    +                             const char *path,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +

    Retrieve all extended attributes in a canonical (sorted) order from +the given path, relative to the provided directory file descriptor. +The target path will not be dereferenced. Currently on Linux, this +API must be used currently to retrieve extended attributes +for symbolic links because while O_PATH exists, it cannot be used +with fgetxattr().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    dfd

    Directory file descriptor

     

    path

    Filesystem path

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    A GVariant of type a(ayay).

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_create_directory_metadata ()

    +
    GVariant *
    +ostree_create_directory_metadata (GFileInfo *dir_info,
    +                                  GVariant *xattrs);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    dir_info

    a GFileInfo containing directory information

     

    xattrs

    Optional extended attributes.

    [allow-none]
    +
    +
    +

    Returns

    +

    A new GVariant containing OSTREE_OBJECT_TYPE_DIR_META.

    +

    [transfer full][not nullable]

    +
    +
    +
    +
    +

    ostree_validate_structureof_objtype ()

    +
    gboolean
    +ostree_validate_structureof_objtype (guchar objtype,
    +                                     GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if objtype +represents a valid object type

    +
    +
    +
    +
    +

    ostree_validate_structureof_csum_v ()

    +
    gboolean
    +ostree_validate_structureof_csum_v (GVariant *checksum,
    +                                    GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    a GVariant of type "ay"

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if checksum +is a valid binary SHA256 checksum

    +
    +
    +
    +
    +

    ostree_validate_structureof_checksum_string ()

    +
    gboolean
    +ostree_validate_structureof_checksum_string
    +                               (const char *checksum,
    +                                GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    checksum

    an ASCII string

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if checksum +is a valid ASCII SHA256 checksum

    +
    +
    +
    +
    +

    ostree_validate_structureof_file_mode ()

    +
    gboolean
    +ostree_validate_structureof_file_mode (guint32 mode,
    +                                       GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    mode

    A Unix filesystem mode

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if mode +represents a valid file type and permissions

    +
    +
    +
    +
    +

    ostree_validate_structureof_commit ()

    +
    gboolean
    +ostree_validate_structureof_commit (GVariant *commit,
    +                                    GError **error);
    +

    Use this to validate the basic structure of commit +, independent of +any other objects it references.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    commit

    A commit object, OSTREE_OBJECT_TYPE_COMMIT

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if commit +is structurally valid

    +
    +
    +
    +
    +

    ostree_validate_structureof_dirtree ()

    +
    gboolean
    +ostree_validate_structureof_dirtree (GVariant *dirtree,
    +                                     GError **error);
    +

    Use this to validate the basic structure of dirtree +, independent of +any other objects it references.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    dirtree

    A dirtree object, OSTREE_OBJECT_TYPE_DIR_TREE

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if dirtree +is structurally valid

    +
    +
    +
    +
    +

    ostree_validate_structureof_dirmeta ()

    +
    gboolean
    +ostree_validate_structureof_dirmeta (GVariant *dirmeta,
    +                                     GError **error);
    +

    Use this to validate the basic structure of dirmeta +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    dirmeta

    A dirmeta object, OSTREE_OBJECT_TYPE_DIR_META

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if dirmeta +is structurally valid

    +
    +
    +
    +
    +

    ostree_commit_get_parent ()

    +
    gchar *
    +ostree_commit_get_parent (GVariant *commit_variant);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    commit_variant

    Variant of type OSTREE_OBJECT_TYPE_COMMIT

     
    +
    +
    +

    Returns

    +

    Checksum of the parent commit of commit_variant +, or NULL +if none.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_commit_get_timestamp ()

    +
    guint64
    +ostree_commit_get_timestamp (GVariant *commit_variant);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    commit_variant

    Commit object

     
    +
    +
    +

    Returns

    +

    timestamp in seconds since the Unix epoch, UTC

    +
    +

    Since: 2016.3

    +
    +
    +
    +

    ostree_commit_metadata_for_bootable ()

    +
    gboolean
    +ostree_commit_metadata_for_bootable (GFile *root,
    +                                     GVariantDict *dict,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Update provided dict + with standard metadata for bootable OSTree commits.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    root

    Root filesystem to be committed

     

    dict

    Dictionary to update

     
    +
    +

    Since: 2021.1

    +
    +
    +
    +

    ostree_commit_get_content_checksum ()

    +
    gchar *
    +ostree_commit_get_content_checksum (GVariant *commit_variant);
    +

    There are use cases where one wants a checksum just of the content of a +commit. OSTree commits by default capture the current timestamp, and may have +additional metadata, which means that re-committing identical content +often results in a new checksum.

    +

    By comparing checksums of content, it's possible to easily distinguish +cases where nothing actually changed.

    +

    The content checksums is simply defined as SHA256(root dirtree_checksum || +root_dirmeta_checksum), i.e. the SHA-256 of the root "dirtree" object's checksum concatenated +with the root "dirmeta" checksum (both in binary form, not hexadecimal).

    +
    +

    Parameters

    +
    +++++ + + + + + +

    commit_variant

    A commit object

     
    +
    +
    +

    Returns

    +

    A SHA-256 hex string, or NULL if commit_variant +is not well-formed.

    +

    [nullable]

    +
    +

    Since: 2018.2

    +
    +
    +
    +

    ostree_commit_get_object_sizes ()

    +
    gboolean
    +ostree_commit_get_object_sizes (GVariant *commit_variant,
    +                                GPtrArray **out_sizes_entries,
    +                                GError **error);
    +

    Reads a commit's "ostree.sizes" metadata and returns an array of +OstreeCommitSizesEntry in out_sizes_entries +. Each element +represents an object in the commit. If the commit does not contain +the "ostree.sizes" metadata, a G_IO_ERROR_NOT_FOUND error will be +returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    commit_variant

    variant of type OSTREE_OBJECT_TYPE_COMMIT.

    [not nullable]

    out_sizes_entries

    return location for an array of object size entries.

    [out][element-type OstreeCommitSizesEntry][transfer container][optional]

    error

    Error

     
    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_commit_sizes_entry_new ()

    +
    OstreeCommitSizesEntry *
    +ostree_commit_sizes_entry_new (const gchar *checksum,
    +                               OstreeObjectType objtype,
    +                               guint64 unpacked,
    +                               guint64 archived);
    +

    Create a new OstreeCommitSizesEntry for representing an object in a +commit's "ostree.sizes" metadata.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    checksum

    object checksum.

    [not nullable]

    objtype

    object type

     

    unpacked

    unpacked object size

     

    archived

    compressed object size

     
    +
    +
    +

    Returns

    +

    a new OstreeCommitSizesEntry.

    +

    [transfer full][nullable]

    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_commit_sizes_entry_copy ()

    +
    OstreeCommitSizesEntry *
    +ostree_commit_sizes_entry_copy (const OstreeCommitSizesEntry *entry);
    +

    Create a copy of the given entry +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    entry

    an OstreeCommitSizesEntry.

    [not nullable]
    +
    +
    +

    Returns

    +

    a new copy of entry +.

    +

    [transfer full][nullable]

    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_commit_sizes_entry_free ()

    +
    void
    +ostree_commit_sizes_entry_free (OstreeCommitSizesEntry *entry);
    +

    Free given entry +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    entry

    an OstreeCommitSizesEntry.

    [transfer full]
    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_check_version ()

    +
    gboolean
    +ostree_check_version (guint required_year,
    +                      guint required_release);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    required_year

    Major/year required

     

    required_release

    Release version required

     
    +
    +
    +

    Returns

    +

    TRUE if current libostree has at least the requested version, FALSE otherwise

    +
    +

    Since: 2017.4

    +
    +
    +
    +

    Types and Values

    +
    +

    OSTREE_MAX_METADATA_SIZE

    +
    #define OSTREE_MAX_METADATA_SIZE (128 * 1024 * 1024)
    +
    +

    Default limit for maximum permitted size in bytes of metadata objects fetched +over HTTP (including repo/config files, refs, and commit/dirtree/dirmeta +objects). This is an arbitrary number intended to mitigate disk space +exhaustion attacks.

    +
    +
    +
    +

    OSTREE_MAX_METADATA_WARN_SIZE

    +
    #define OSTREE_MAX_METADATA_WARN_SIZE (7 * 1024 * 1024)
    +
    +

    This variable is no longer meaningful, it is kept only for compatibility.

    +
    +
    +
    +

    enum OstreeObjectType

    +

    Enumeration for core object types; OSTREE_OBJECT_TYPE_FILE is for +content, the other types are metadata.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_OBJECT_TYPE_FILE

    +

    Content; regular file, symbolic link

    +
     

    OSTREE_OBJECT_TYPE_DIR_TREE

    +

    List of children (trees or files), and metadata

    +
     

    OSTREE_OBJECT_TYPE_DIR_META

    +

    Directory metadata

    +
     

    OSTREE_OBJECT_TYPE_COMMIT

    +

    Toplevel object, refers to tree and dirmeta for root

    +
     

    OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT

    +

    Toplevel object, refers to a deleted commit

    +
     

    OSTREE_OBJECT_TYPE_COMMIT_META

    +

    Detached metadata for a commit

    +
     

    OSTREE_OBJECT_TYPE_PAYLOAD_LINK

    +

    Symlink to a .file given its checksum on the payload only.

    +
     

    OSTREE_OBJECT_TYPE_FILE_XATTRS

    +

    Detached xattrs content, for 'bare-split-xattrs' mode.

    +
     

    OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK

    +

    Hardlink to a .file-xattrs given the checksum of its .file +object.

    +
     
    +
    +
    +
    +
    +

    OSTREE_OBJECT_TYPE_LAST

    +
    #define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_FILE_XATTRS_LINK
    +
    +

    Last valid object type; use this to validate ranges.

    +
    +
    +
    +

    OSTREE_DIRMETA_GVARIANT_STRING

    +
    #define OSTREE_DIRMETA_GVARIANT_STRING "(uuua(ayay))"
    +
    +
    +
    +
    +

    OSTREE_DIRMETA_GVARIANT_FORMAT

    +
    #define OSTREE_DIRMETA_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_DIRMETA_GVARIANT_STRING)
    +
    +
      +
    • u - uid (big-endian)

    • +
    • u - gid (big-endian)

    • +
    • u - mode (big-endian)

    • +
    • a(ayay) - xattrs

    • +
    +
    +
    +
    +

    OSTREE_FILEMETA_GVARIANT_STRING

    +
    #define OSTREE_FILEMETA_GVARIANT_STRING "(uuua(ayay))"
    +
    +
    +
    +
    +

    OSTREE_FILEMETA_GVARIANT_FORMAT

    +
    #define OSTREE_FILEMETA_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_FILEMETA_GVARIANT_STRING)
    +
    +

    This is not a regular object type, but used as an xattr on a .file object +in bare-user repositories. This allows us to store metadata information that we +can't store in the real filesystem but we can still use a regular .file object +that we can hardlink to in the case of a user-mode checkout.

    +
      +
    • u - uid (big-endian)

    • +
    • u - gid (big-endian)

    • +
    • u - mode (big-endian)

    • +
    • a(ayay) - xattrs

    • +
    +
    +
    +
    +

    OSTREE_TREE_GVARIANT_STRING

    +
    #define OSTREE_TREE_GVARIANT_STRING "(a(say)a(sayay))"
    +
    +
    +
    +
    +

    OSTREE_TREE_GVARIANT_FORMAT

    +
    #define OSTREE_TREE_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_TREE_GVARIANT_STRING)
    +
    +
      +
    • a(say) - array of (filename, checksum) for files

    • +
    • a(sayay) - array of (dirname, tree_checksum, meta_checksum) for directories

    • +
    +
    +
    +
    +

    OSTREE_COMMIT_GVARIANT_STRING

    +
    #define OSTREE_COMMIT_GVARIANT_STRING "(a{sv}aya(say)sstayay)"
    +
    +
    +
    +
    +

    OSTREE_COMMIT_GVARIANT_FORMAT

    +
    #define OSTREE_COMMIT_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_COMMIT_GVARIANT_STRING)
    +
    +
      +
    • a{sv} - Metadata

    • +
    • ay - parent checksum (empty string for initial)

    • +
    • a(say) - Related objects

    • +
    • s - subject

    • +
    • s - body

    • +
    • t - Timestamp in seconds since the epoch (UTC, big-endian)

    • +
    • ay - Root tree contents

    • +
    • ay - Root tree metadata

    • +
    +
    +
    +
    +

    OSTREE_SUMMARY_GVARIANT_STRING

    +
    #define OSTREE_SUMMARY_GVARIANT_STRING "(a(s(taya{sv}))a{sv})"
    +
    +
    +
    +
    +

    OSTREE_SUMMARY_GVARIANT_FORMAT

    +
    #define OSTREE_SUMMARY_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_SUMMARY_GVARIANT_STRING)
    +
    +
      +
    • a(s(taya{sv})) - Map of ref name -> (latest commit size, latest commit checksum, additional +metadata), sorted by ref name

    • +
    • +

      a{sv} - Additional metadata, at the current time the following are defined:

      +
        +
      • key: "ostree.static-deltas", value: a{sv}, static delta name -> 32 bytes of checksum

      • +
      • key: "ostree.summary.last-modified", value: t, timestamp (seconds since +the Unix epoch in UTC, big-endian) when the summary was last regenerated +(similar to the HTTP Last-Modified header)

      • +
      • key: "ostree.summary.expires", value: t, timestamp (seconds since the +Unix epoch in UTC, big-endian) after which the summary is considered +stale and should be re-downloaded if possible (similar to the HTTP +Expires header)

      • +
      +
    • +
    +

    The currently defined keys for the a{sv} of additional metadata for each commit are:

    +
      +
    • key: ostree.commit.timestamp, value: t, timestamp (seconds since the +Unix epoch in UTC, big-endian) when the commit was committed

    • +
    • key: ostree.commit.version, value: s, the version value from the +commit's metadata if it was defined. Since: 2022.2

    • +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-GPG-signature-verification-results.html b/reference/ostree-GPG-signature-verification-results.html new file mode 100644 index 0000000000..fae0c5522c --- /dev/null +++ b/reference/ostree-GPG-signature-verification-results.html @@ -0,0 +1,757 @@ + + + + +GPG signature verification results: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    GPG signature verification results

    +

    GPG signature verification results — Inspect detached GPG signatures

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +guint + +ostree_gpg_verify_result_count_all () +
    +guint + +ostree_gpg_verify_result_count_valid () +
    +gboolean + +ostree_gpg_verify_result_lookup () +
    +GVariant * + +ostree_gpg_verify_result_get () +
    +GVariant * + +ostree_gpg_verify_result_get_all () +
    +void + +ostree_gpg_verify_result_describe () +
    +void + +ostree_gpg_verify_result_describe_variant () +
    +gboolean + +ostree_gpg_verify_result_require_valid_signature () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + + + + + + + + + +
    enumOstreeGpgError
    typedefOstreeGpgVerifyResult
    enumOstreeGpgSignatureAttr
    enumOstreeGpgSignatureFormatFlags
    +
    +
    +

    Description

    +

    OstreeGpgVerifyResult contains verification details for GPG signatures +read from a detached OstreeRepo metadata object.

    +

    Use ostree_gpg_verify_result_count_all() and +ostree_gpg_verify_result_count_valid() to quickly check overall signature +validity.

    +

    Use ostree_gpg_verify_result_lookup() to find a signature by the key ID +or fingerprint of the signing key.

    +

    For more in-depth inspection, such as presenting signature details to the +user, pass an array of attribute values to ostree_gpg_verify_result_get() +or get all signature details with ostree_gpg_verify_result_get_all().

    +
    +
    +

    Functions

    +
    +

    ostree_gpg_verify_result_count_all ()

    +
    guint
    +ostree_gpg_verify_result_count_all (OstreeGpgVerifyResult *result);
    +

    Counts all the signatures in result +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    result

    an OstreeGpgVerifyResult

     
    +
    +
    +

    Returns

    +

    signature count

    +
    +
    +
    +
    +

    ostree_gpg_verify_result_count_valid ()

    +
    guint
    +ostree_gpg_verify_result_count_valid (OstreeGpgVerifyResult *result);
    +

    Counts only the valid signatures in result +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    result

    an OstreeGpgVerifyResult

     
    +
    +
    +

    Returns

    +

    valid signature count

    +
    +
    +
    +
    +

    ostree_gpg_verify_result_lookup ()

    +
    gboolean
    +ostree_gpg_verify_result_lookup (OstreeGpgVerifyResult *result,
    +                                 const gchar *key_id,
    +                                 guint *out_signature_index);
    +

    Searches result + for a signature signed by key_id +. If a match is found, +the function returns TRUE and sets out_signature_index + so that further +signature details can be obtained through ostree_gpg_verify_result_get(). +If no match is found, the function returns FALSE and leaves +out_signature_index + unchanged.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    result

    an OstreeGpgVerifyResult

     

    key_id

    a GPG key ID or fingerprint

     

    out_signature_index

    return location for the index of the signature +signed by key_id +, or NULL.

    [out]
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_gpg_verify_result_get ()

    +
    GVariant *
    +ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
    +                              guint signature_index,
    +                              OstreeGpgSignatureAttr *attrs,
    +                              guint n_attrs);
    +

    Builds a GVariant tuple of requested attributes for the GPG signature at +signature_index + in result +. See the OstreeGpgSignatureAttr description +for the GVariantType of each available attribute.

    +

    It is a programmer error to request an invalid OstreeGpgSignatureAttr or +an invalid signature_index +. Use ostree_gpg_verify_result_count_all() to +find the number of signatures in result +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    result

    an OstreeGpgVerifyResult

     

    signature_index

    which signature to get attributes from

     

    attrs

    Array of requested attributes.

    [array length=n_attrs]

    n_attrs

    Length of the attrs +array

     
    +
    +
    +

    Returns

    +

    a new, floating, GVariant tuple.

    +

    [transfer floating]

    +
    +
    +
    +
    +

    ostree_gpg_verify_result_get_all ()

    +
    GVariant *
    +ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
    +                                  guint signature_index);
    +

    Builds a GVariant tuple of all available attributes for the GPG signature +at signature_index + in result +.

    +

    The child values in the returned GVariant tuple are ordered to match the +OstreeGpgSignatureAttr enumeration, which means the enum values can be +used as index values in functions like g_variant_get_child(). See the +OstreeGpgSignatureAttr description for the GVariantType of each +available attribute.

    +

    + The OstreeGpgSignatureAttr enumeration may be extended in the future + with new attributes, which would affect the GVariant tuple returned by + this function. While the position and type of current child values in + the GVariant tuple will not change, to avoid backward-compatibility + issues please do not depend on the tuple's overall size or + type signature. +

    +

    It is a programmer error to request an invalid signature_index +. Use +ostree_gpg_verify_result_count_all() to find the number of signatures in +result +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    result

    an OstreeGpgVerifyResult

     

    signature_index

    which signature to get attributes from

     
    +
    +
    +

    Returns

    +

    a new, floating, GVariant tuple.

    +

    [transfer floating]

    +
    +
    +
    +
    +

    ostree_gpg_verify_result_describe ()

    +
    void
    +ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result,
    +                                   guint signature_index,
    +                                   GString *output_buffer,
    +                                   const gchar *line_prefix,
    +                                   OstreeGpgSignatureFormatFlags flags);
    +

    Appends a brief, human-readable description of the GPG signature at +signature_index + in result + to the output_buffer +. The description +spans multiple lines. A line_prefix + string, if given, will precede +each line of the description.

    +

    The flags + argument is reserved for future variations to the description +format. Currently must be 0.

    +

    It is a programmer error to request an invalid signature_index +. Use +ostree_gpg_verify_result_count_all() to find the number of signatures in +result +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    result

    an OstreeGpgVerifyResult

     

    signature_index

    which signature to describe

     

    output_buffer

    a GString to hold the description

     

    line_prefix

    optional line prefix string.

    [allow-none]

    flags

    flags to adjust the description format

     
    +
    +
    +
    +
    +

    ostree_gpg_verify_result_describe_variant ()

    +
    void
    +ostree_gpg_verify_result_describe_variant
    +                               (GVariant *variant,
    +                                GString *output_buffer,
    +                                const gchar *line_prefix,
    +                                OstreeGpgSignatureFormatFlags flags);
    +

    Similar to ostree_gpg_verify_result_describe() but takes a GVariant of +all attributes for a GPG signature instead of an OstreeGpgVerifyResult +and signature index.

    +

    The variant + MUST have been created by +ostree_gpg_verify_result_get_all().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    variant

    a GVariant from ostree_gpg_verify_result_get_all()

     

    output_buffer

    a GString to hold the description

     

    line_prefix

    optional line prefix string.

    [allow-none]

    flags

    flags to adjust the description format

     
    +
    +
    +
    +
    +

    ostree_gpg_verify_result_require_valid_signature ()

    +
    gboolean
    +ostree_gpg_verify_result_require_valid_signature
    +                               (OstreeGpgVerifyResult *result,
    +                                GError **error);
    +

    Checks if the result contains at least one signature from the +trusted keyring. You can call this function immediately after +ostree_repo_verify_summary() or ostree_repo_verify_commit_ext() - +it will handle the NULL result + and filled error + too.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    result

    an OstreeGpgVerifyResult.

    [nullable]

    error

    A GError

     
    +
    +
    +

    Returns

    +

    TRUE if result +was not NULL and had at least one +signature from trusted keyring, otherwise FALSE

    +
    +

    Since: 2016.6

    +
    +
    +
    +

    Types and Values

    +
    +

    enum OstreeGpgError

    +

    Errors returned by signature creation and verification operations in OSTree. +These may be returned by any API which creates or verifies signatures.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_GPG_ERROR_NO_SIGNATURE

    +

    A signature was expected, but not found.

    +
     

    OSTREE_GPG_ERROR_INVALID_SIGNATURE

    +

    A signature was malformed.

    +
     

    OSTREE_GPG_ERROR_MISSING_KEY

    +

    A signature was found, but was created with a key not in the +configured keyrings.

    +
     

    OSTREE_GPG_ERROR_EXPIRED_SIGNATURE

    +

    A signature was expired. Since: 2020.1.

    +
     

    OSTREE_GPG_ERROR_EXPIRED_KEY

    +

    A signature was found, but the key used to +sign it has expired. Since: 2020.1.

    +
     

    OSTREE_GPG_ERROR_REVOKED_KEY

    +

    A signature was found, but the key used to +sign it has been revoked. Since: 2020.1.

    +
     
    +
    +

    Since: 2017.10

    +
    +
    +
    +

    OstreeGpgVerifyResult

    +
    typedef struct OstreeGpgVerifyResult OstreeGpgVerifyResult;
    +
    +

    Private instance structure.

    +
    +
    +
    +

    enum OstreeGpgSignatureAttr

    +

    Signature attributes available from an OstreeGpgVerifyResult. +The attribute's GVariantType is shown in brackets.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_GPG_SIGNATURE_ATTR_VALID

    +

    [G_VARIANT_TYPE_BOOLEAN] Is the signature valid?

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED

    +

    [G_VARIANT_TYPE_BOOLEAN] Has the signature expired?

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_KEY_EXPIRED

    +

    [G_VARIANT_TYPE_BOOLEAN] Has the signing key expired?

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_KEY_REVOKED

    +

    [G_VARIANT_TYPE_BOOLEAN] Has the signing key been revoked?

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING

    +

    [G_VARIANT_TYPE_BOOLEAN] Is the signing key missing?

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT

    +

    [G_VARIANT_TYPE_STRING] Fingerprint of the signing key

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP

    +

    [G_VARIANT_TYPE_INT64] Signature creation Unix timestamp

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP

    +

    [G_VARIANT_TYPE_INT64] Signature expiration Unix timestamp (0 if no +expiration)

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME

    +

    [G_VARIANT_TYPE_STRING] Name of the public key algorithm used to create +the signature

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_HASH_ALGO_NAME

    +

    [G_VARIANT_TYPE_STRING] Name of the hash algorithm used to create the +signature

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_USER_NAME

    +

    [G_VARIANT_TYPE_STRING] The name of the signing key's primary user

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL

    +

    [G_VARIANT_TYPE_STRING] The email address of the signing key's primary +user

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT_PRIMARY

    +

    [G_VARIANT_TYPE_STRING] Fingerprint of the signing key's primary key +(will be the same as OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT if the +the signature is already from the primary key rather than a subkey, +and will be the empty string if the key is missing.)

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP

    +

    [G_VARIANT_TYPE_INT64] Key expiration Unix timestamp (0 if no +expiration or if the key is missing)

    +
     

    OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP_PRIMARY

    +

    [G_VARIANT_TYPE_INT64] Key expiration Unix timestamp of the signing key's +primary key (will be the same as OSTREE_GPG_SIGNATURE_ATTR_KEY_EXP_TIMESTAMP +if the signing key is the primary key and 0 if no expiration or if the key +is missing)

    +
     
    +
    +
    +
    +
    +

    enum OstreeGpgSignatureFormatFlags

    +

    Formatting flags for ostree_gpg_verify_result_describe(). Currently +there's only one possible output format, but this enumeration allows +for future variations.

    +
    +

    Members

    +
    +++++ + + + + + +

    OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT

    +

    Use the default output format

    +
     
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-In-memory-modifiable-filesystem-tree.html b/reference/ostree-In-memory-modifiable-filesystem-tree.html new file mode 100644 index 0000000000..f06af25585 --- /dev/null +++ b/reference/ostree-In-memory-modifiable-filesystem-tree.html @@ -0,0 +1,685 @@ + + + + +In-memory modifiable filesystem tree: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    In-memory modifiable filesystem tree

    +

    In-memory modifiable filesystem tree — Modifiable filesystem tree

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeMutableTree * + +ostree_mutable_tree_new () +
    +OstreeMutableTree * + +ostree_mutable_tree_new_from_commit () +
    +OstreeMutableTree * + +ostree_mutable_tree_new_from_checksum () +
    +gboolean + +ostree_mutable_tree_check_error () +
    +void + +ostree_mutable_tree_set_metadata_checksum () +
    const char * + +ostree_mutable_tree_get_metadata_checksum () +
    +void + +ostree_mutable_tree_set_contents_checksum () +
    const char * + +ostree_mutable_tree_get_contents_checksum () +
    +gboolean + +ostree_mutable_tree_replace_file () +
    +gboolean + +ostree_mutable_tree_remove () +
    +gboolean + +ostree_mutable_tree_ensure_dir () +
    +gboolean + +ostree_mutable_tree_lookup () +
    +gboolean + +ostree_mutable_tree_ensure_parent_dirs () +
    +gboolean + +ostree_mutable_tree_walk () +
    +GHashTable * + +ostree_mutable_tree_get_subdirs () +
    +GHashTable * + +ostree_mutable_tree_get_files () +
    +gboolean + +ostree_mutable_tree_fill_empty_from_dirtree () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    typedefOstreeMutableTree
    +
    +
    +

    Description

    +

    In order to commit content into an OstreeRepo, it must first be +imported into an OstreeMutableTree. There are several high level +APIs to create an initiable OstreeMutableTree from a physical +filesystem directory, but they may also be computed +programmatically.

    +
    +
    +

    Functions

    +
    +

    ostree_mutable_tree_new ()

    +
    OstreeMutableTree *
    +ostree_mutable_tree_new (void);
    +
    +

    Returns

    +

    A new tree.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_mutable_tree_new_from_commit ()

    +
    OstreeMutableTree *
    +ostree_mutable_tree_new_from_commit (OstreeRepo *repo,
    +                                     const char *rev,
    +                                     GError **error);
    +

    Creates a new OstreeMutableTree with the contents taken from the given commit. +The data will be loaded from the repo lazily as needed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    repo

    The repo which contains the objects refered by the checksums.

     

    rev

    ref or SHA-256 checksum

     
    +
    +
    +

    Returns

    +

    A new tree.

    +

    [transfer full]

    +
    +

    Since: 2021.5

    +
    +
    +
    +

    ostree_mutable_tree_new_from_checksum ()

    +
    OstreeMutableTree *
    +ostree_mutable_tree_new_from_checksum (OstreeRepo *repo,
    +                                       const char *contents_checksum,
    +                                       const char *metadata_checksum);
    +

    Creates a new OstreeMutableTree with the contents taken from the given repo +and checksums. The data will be loaded from the repo lazily as needed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    repo

    The repo which contains the objects refered by the checksums.

     

    contents_checksum

    dirtree checksum

     

    metadata_checksum

    dirmeta checksum

     
    +
    +
    +

    Returns

    +

    A new tree.

    +

    [transfer full]

    +
    +

    Since: 2018.7

    +
    +
    +
    +

    ostree_mutable_tree_check_error ()

    +
    gboolean
    +ostree_mutable_tree_check_error (OstreeMutableTree *self,
    +                                 GError **error);
    +

    In some cases, a tree may be in a "lazy" state that loads +data in the background; if an error occurred during a non-throwing +API call, it will have been cached. This function checks for a +cached error. The tree remains in error state.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Tree

     
    +
    +
    +

    Returns

    +

    TRUE on success

    +
    +

    Since: 2018.7

    +
    +
    +
    +

    ostree_mutable_tree_set_metadata_checksum ()

    +
    void
    +ostree_mutable_tree_set_metadata_checksum
    +                               (OstreeMutableTree *self,
    +                                const char *checksum);
    +
    +
    +
    +

    ostree_mutable_tree_get_metadata_checksum ()

    +
    const char *
    +ostree_mutable_tree_get_metadata_checksum
    +                               (OstreeMutableTree *self);
    +
    +
    +
    +

    ostree_mutable_tree_set_contents_checksum ()

    +
    void
    +ostree_mutable_tree_set_contents_checksum
    +                               (OstreeMutableTree *self,
    +                                const char *checksum);
    +
    +
    +
    +

    ostree_mutable_tree_get_contents_checksum ()

    +
    const char *
    +ostree_mutable_tree_get_contents_checksum
    +                               (OstreeMutableTree *self);
    +
    +
    +
    +

    ostree_mutable_tree_replace_file ()

    +
    gboolean
    +ostree_mutable_tree_replace_file (OstreeMutableTree *self,
    +                                  const char *name,
    +                                  const char *checksum,
    +                                  GError **error);
    +
    +
    +
    +

    ostree_mutable_tree_remove ()

    +
    gboolean
    +ostree_mutable_tree_remove (OstreeMutableTree *self,
    +                            const char *name,
    +                            gboolean allow_noent,
    +                            GError **error);
    +

    Remove the file or subdirectory named name + from the mutable tree self +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Tree

     

    name

    Name of file or subdirectory to remove

     

    allow_noent

    If FALSE +, an error will be thrown if name +does not exist in the tree

     

    error

    a GError

     
    +
    +

    Since: 2018.9

    +
    +
    +
    +

    ostree_mutable_tree_ensure_dir ()

    +
    gboolean
    +ostree_mutable_tree_ensure_dir (OstreeMutableTree *self,
    +                                const char *name,
    +                                OstreeMutableTree **out_subdir,
    +                                GError **error);
    +

    Returns the subdirectory of self with filename name +, creating an empty one +it if it doesn't exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Tree

     

    name

    Name of subdirectory of self to retrieve/creates

     

    out_subdir

    the subdirectory.

    [out][transfer full][optional]

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_mutable_tree_lookup ()

    +
    gboolean
    +ostree_mutable_tree_lookup (OstreeMutableTree *self,
    +                            const char *name,
    +                            char **out_file_checksum,
    +                            OstreeMutableTree **out_subdir,
    +                            GError **error);
    +

    Lookup name + and returns out_file_checksum + or out_subdir + depending on its +file type.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Tree

     

    name

    name

     

    out_file_checksum

    checksum.

    [out][transfer full][nullable][optional]

    out_subdir

    subdirectory.

    [out][transfer full][nullable][optional]

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success and either out_file_checksum +or out_subdir +are +filled, FALSE otherwise.

    +
    +
    +
    +
    +

    ostree_mutable_tree_ensure_parent_dirs ()

    +
    gboolean
    +ostree_mutable_tree_ensure_parent_dirs
    +                               (OstreeMutableTree *self,
    +                                GPtrArray *split_path,
    +                                const char *metadata_checksum,
    +                                OstreeMutableTree **out_parent,
    +                                GError **error);
    +

    Create all parent trees necessary for the given split_path + to +exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Tree

     

    split_path

    File path components.

    [element-type utf8]

    metadata_checksum

    SHA256 checksum for metadata

     

    out_parent

    The parent tree.

    [out][transfer full][optional]

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_mutable_tree_walk ()

    +
    gboolean
    +ostree_mutable_tree_walk (OstreeMutableTree *self,
    +                          GPtrArray *split_path,
    +                          guint start,
    +                          OstreeMutableTree **out_subdir,
    +                          GError **error);
    +

    Traverse start + number of elements starting from split_path +; the +child will be returned in out_subdir +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Tree

     

    split_path

    Split pathname.

    [element-type utf8]

    start

    Descend from this number of elements in split_path +

     

    out_subdir

    Target parent.

    [out][transfer full]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_mutable_tree_get_subdirs ()

    +
    GHashTable *
    +ostree_mutable_tree_get_subdirs (OstreeMutableTree *self);
    +
    +

    Returns

    +

    All children directories.

    +

    [transfer none][element-type utf8 OstreeMutableTree]

    +
    +
    +
    +
    +

    ostree_mutable_tree_get_files ()

    +
    GHashTable *
    +ostree_mutable_tree_get_files (OstreeMutableTree *self);
    +
    +

    Returns

    +

    All children files (the value is a checksum).

    +

    [transfer none][element-type utf8 utf8]

    +
    +
    +
    +
    +

    ostree_mutable_tree_fill_empty_from_dirtree ()

    +
    gboolean
    +ostree_mutable_tree_fill_empty_from_dirtree
    +                               (OstreeMutableTree *self,
    +                                OstreeRepo *repo,
    +                                const char *contents_checksum,
    +                                const char *metadata_checksum);
    +

    Merges self + with the tree given by contents_checksum + and +metadata_checksum +, but only if it's possible without writing new objects to +the repo +. We can do this if either self + is empty, the tree given by +contents_checksum + is empty or if both trees already have the same +contents_checksum +.

    +
    +

    Returns

    +

    TRUE +if merge was successful, FALSE +if it was not possible.

    +

    This function enables optimisations when composing trees. The provided +checksums are not loaded or checked when this function is called. Instead +the contents will be loaded only when needed.

    +
    +

    Since: 2018.7

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeMutableTree

    +
    typedef struct OstreeMutableTree OstreeMutableTree;
    +
    +

    Private instance structure.

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-OstreeRepo.html b/reference/ostree-OstreeRepo.html new file mode 100644 index 0000000000..4410a3982c --- /dev/null +++ b/reference/ostree-OstreeRepo.html @@ -0,0 +1,10655 @@ + + + + +OstreeRepo: Content-addressed object store: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    OstreeRepo: Content-addressed object store

    +

    OstreeRepo: Content-addressed object store — A git-like storage system for operating system binaries

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +gboolean + +ostree_repo_mode_from_string () +
    +OstreeRepo * + +ostree_repo_open_at () +
    +OstreeRepo * + +ostree_repo_new () +
    +OstreeRepo * + +ostree_repo_new_for_sysroot_path () +
    +OstreeRepo * + +ostree_repo_new_default () +
    +gboolean + +ostree_repo_open () +
    +void + +ostree_repo_set_disable_fsync () +
    +gboolean + +ostree_repo_get_disable_fsync () +
    +gboolean + +ostree_repo_is_system () +
    +gboolean + +ostree_repo_is_writable () +
    +OstreeRepo * + +ostree_repo_create_at () +
    +gboolean + +ostree_repo_create () +
    const gchar * + +ostree_repo_get_collection_id () +
    const gchar * + +ostree_repo_get_bootloader () +
    +GFile * + +ostree_repo_get_path () +
    +OstreeRepoMode + +ostree_repo_get_mode () +
    +gboolean + +ostree_repo_get_min_free_space_bytes () +
    +GKeyFile * + +ostree_repo_get_config () +
    +int + +ostree_repo_get_dfd () +
    const gchar *const * + +ostree_repo_get_default_repo_finders () +
    +gboolean + +ostree_repo_lock_pop () +
    +gboolean + +ostree_repo_lock_push () +
    +OstreeRepoAutoLock * + +ostree_repo_auto_lock_push () +
    +void + +ostree_repo_auto_lock_cleanup () +
    +guint + +ostree_repo_hash () +
    +gboolean + +ostree_repo_equal () +
    +GKeyFile * + +ostree_repo_copy_config () +
    +gboolean + +ostree_repo_remote_add () +
    +gboolean + +ostree_repo_remote_delete () +
    +gboolean + +ostree_repo_remote_change () +
    +char ** + +ostree_repo_remote_list () +
    +gboolean + +ostree_repo_remote_list_collection_refs () +
    +gboolean + +ostree_repo_remote_get_url () +
    +gboolean + +ostree_repo_remote_get_gpg_verify () +
    +gboolean + +ostree_repo_remote_get_gpg_verify_summary () +
    +gboolean + +ostree_repo_remote_get_gpg_keys () +
    +gboolean + +ostree_repo_remote_gpg_import () +
    +gboolean + +ostree_repo_remote_fetch_summary () +
    +gboolean + +ostree_repo_remote_fetch_summary_with_options () +
    +gboolean + +ostree_repo_reload_config () +
    +gboolean + +ostree_repo_get_remote_boolean_option () +
    +gboolean + +ostree_repo_get_remote_list_option () +
    +gboolean + +ostree_repo_get_remote_option () +
    +OstreeRepo * + +ostree_repo_get_parent () +
    +gboolean + +ostree_repo_write_config () +
    +gboolean + +ostree_repo_scan_hardlinks () +
    +gboolean + +ostree_repo_prepare_transaction () +
    +gboolean + +ostree_repo_commit_transaction () +
    +gboolean + +ostree_repo_abort_transaction () +
    +void + +ostree_repo_transaction_set_refspec () +
    +void + +ostree_repo_transaction_set_collection_ref () +
    +void + +ostree_repo_transaction_set_ref () +
    +gboolean + +ostree_repo_set_ref_immediate () +
    +gboolean + +ostree_repo_set_alias_ref_immediate () +
    +gboolean + +ostree_repo_set_cache_dir () +
    +gboolean + +ostree_repo_set_collection_id () +
    +gboolean + +ostree_repo_set_collection_ref_immediate () +
    +gboolean + +ostree_repo_sign_delta () +
    +gboolean + +ostree_repo_has_object () +
    +gboolean + +ostree_repo_mark_commit_partial () +
    +gboolean + +ostree_repo_mark_commit_partial_reason () +
    +gboolean + +ostree_repo_write_metadata () +
    +void + +ostree_repo_write_metadata_async () +
    +gboolean + +ostree_repo_write_metadata_finish () +
    +gboolean + +ostree_repo_write_content () +
    +OstreeContentWriter * + +ostree_repo_write_regfile () +
    +char * + +ostree_repo_write_regfile_inline () +
    +char * + +ostree_repo_write_symlink () +
    +gboolean + +ostree_repo_write_metadata_trusted () +
    +gboolean + +ostree_repo_write_metadata_stream_trusted () +
    +gboolean + +ostree_repo_write_content_trusted () +
    +void + +ostree_repo_write_content_async () +
    +gboolean + +ostree_repo_write_content_finish () +
    +gboolean + +ostree_repo_resolve_rev () +
    +gboolean + +ostree_repo_resolve_rev_ext () +
    +gboolean + +ostree_repo_list_refs () +
    +gboolean + +ostree_repo_list_refs_ext () +
    +gboolean + +ostree_repo_list_collection_refs () +
    +gboolean + +ostree_repo_remote_list_refs () +
    +gboolean + +ostree_repo_resolve_collection_ref () +
    +gboolean + +ostree_repo_load_variant () +
    +gboolean + +ostree_repo_load_commit () +
    +gboolean + +ostree_repo_load_variant_if_exists () +
    +gboolean + +ostree_repo_load_file () +
    +gboolean + +ostree_repo_load_object_stream () +
    +gboolean + +ostree_repo_query_object_storage_size () +
    +gboolean + +ostree_repo_import_object_from () +
    +gboolean + +ostree_repo_import_object_from_with_trust () +
    +gboolean + +ostree_repo_import_archive_to_mtree () +
    +gboolean + +ostree_repo_export_tree_to_archive () +
    +gboolean + +ostree_repo_delete_object () +
    +gboolean + +ostree_repo_fsck_object () +
    +OstreeRepoCommitFilterResult + +(*OstreeRepoCommitFilter) () +
    +OstreeRepoCommitModifier * + +ostree_repo_commit_modifier_new () +
    +GVariant * + +(*OstreeRepoCommitModifierXattrCallback) () +
    +void + +ostree_repo_commit_modifier_set_xattr_callback () +
    +void + +ostree_repo_commit_modifier_set_sepolicy () +
    +gboolean + +ostree_repo_commit_modifier_set_sepolicy_from_commit () +
    +void + +ostree_repo_commit_modifier_set_devino_cache () +
    +OstreeRepoCommitModifier * + +ostree_repo_commit_modifier_ref () +
    +void + +ostree_repo_commit_modifier_unref () +
    +OstreeRepoDevInoCache * + +ostree_repo_devino_cache_new () +
    +OstreeRepoDevInoCache * + +ostree_repo_devino_cache_ref () +
    +void + +ostree_repo_devino_cache_unref () +
    +GType + +ostree_repo_devino_cache_get_type () +
    +gboolean + +ostree_repo_write_directory_to_mtree () +
    +gboolean + +ostree_repo_write_dfd_to_mtree () +
    +gboolean + +ostree_repo_write_archive_to_mtree () +
    +gboolean + +ostree_repo_write_archive_to_mtree_from_fd () +
    +gboolean + +ostree_repo_write_mtree () +
    +gboolean + +ostree_repo_write_commit () +
    +gboolean + +ostree_repo_write_commit_with_time () +
    +gboolean + +ostree_repo_read_commit_detached_metadata () +
    +gboolean + +ostree_repo_write_commit_detached_metadata () +
    +gboolean + +ostree_repo_commit_add_composefs_metadata () +
    +void + +ostree_repo_checkout_at_options_set_devino () +
    +gboolean + +ostree_repo_checkout_tree () +
    +gboolean + +ostree_repo_checkout_tree_at () +
    +gboolean + +ostree_repo_checkout_at () +
    +gboolean + +ostree_repo_checkout_gc () +
    +gboolean + +ostree_repo_read_commit () +
    +gboolean + +ostree_repo_list_objects () +
    +gboolean + +ostree_repo_list_commit_objects_starting_with () +
    +gboolean + +ostree_repo_list_static_delta_names () +
    +gboolean + +ostree_repo_list_static_delta_indexes () +
    +gboolean + +ostree_repo_static_delta_reindex () +
    +gboolean + +ostree_repo_static_delta_generate () +
    +gboolean + +ostree_repo_static_delta_execute_offline_with_signature () +
    +gboolean + +ostree_repo_static_delta_execute_offline () +
    +gboolean + +ostree_repo_static_delta_verify_signature () +
    +GHashTable * + +ostree_repo_traverse_new_reachable () +
    +GHashTable * + +ostree_repo_traverse_new_parents () +
    +char ** + +ostree_repo_traverse_parents_get_commits () +
    +gboolean + +ostree_repo_traverse_commit () +
    +gboolean + +ostree_repo_traverse_commit_union () +
    +gboolean + +ostree_repo_traverse_commit_union_with_parents () +
    +gboolean + +ostree_repo_traverse_commit_with_flags () +
    +void + +ostree_repo_commit_traverse_iter_cleanup () +
    +void + +ostree_repo_commit_traverse_iter_clear () +
    +void + +ostree_repo_commit_traverse_iter_get_dir () +
    +void + +ostree_repo_commit_traverse_iter_get_file () +
    +gboolean + +ostree_repo_commit_traverse_iter_init_commit () +
    +gboolean + +ostree_repo_commit_traverse_iter_init_dirtree () +
    +OstreeRepoCommitIterResult + +ostree_repo_commit_traverse_iter_next () +
    +gboolean + +ostree_repo_prune () +
    +gboolean + +ostree_repo_prune_static_deltas () +
    +gboolean + +ostree_repo_traverse_reachable_refs () +
    +gboolean + +ostree_repo_prune_from_reachable () +
    +gboolean + +ostree_repo_pull () +
    +gboolean + +ostree_repo_pull_one_dir () +
    +gboolean + +ostree_repo_pull_with_options () +
    +void + +ostree_repo_pull_default_console_progress_changed () +
    +gboolean + +ostree_repo_sign_commit () +
    +gboolean + +ostree_repo_append_gpg_signature () +
    +gboolean + +ostree_repo_add_gpg_signature_summary () +
    +gboolean + +ostree_repo_gpg_sign_data () +
    +OstreeGpgVerifyResult * + +ostree_repo_gpg_verify_data () +
    +gboolean + +ostree_repo_signature_verify_commit_data () +
    +gboolean + +ostree_repo_verify_commit () +
    +OstreeGpgVerifyResult * + +ostree_repo_verify_commit_ext () +
    +OstreeGpgVerifyResult * + +ostree_repo_verify_commit_for_remote () +
    +OstreeGpgVerifyResult * + +ostree_repo_verify_summary () +
    +gboolean + +ostree_repo_regenerate_metadata () +
    +gboolean + +ostree_repo_regenerate_summary () +
    +
    + +
    +

    Description

    +

    The OstreeRepo is like git, a content-addressed object store. +Unlike git, it records uid, gid, and extended attributes.

    +

    There are four possible "modes" for an OstreeRepo; OSTREE_REPO_MODE_BARE +is very simple - content files are represented exactly as they are, and +checkouts are just hardlinks. OSTREE_REPO_MODE_BARE_USER is similar, except +the uid/gids are not set on the files, and checkouts as hardlinks work only +for user checkouts. OSTREE_REPO_MODE_BARE_USER_ONLY is the same as +BARE_USER, but all metadata is not stored, so it can only be used for user +checkouts. This mode does not require xattrs. A OSTREE_REPO_MODE_ARCHIVE +(also known as OSTREE_REPO_MODE_ARCHIVE_Z2) repository in contrast stores +content files zlib-compressed. It is suitable for non-root-owned +repositories that can be served via a static HTTP server.

    +

    Creating an OstreeRepo does not invoke any file I/O, and thus needs +to be initialized, either from existing contents or as a new +repository. If you have an existing repo, use ostree_repo_open() +to load it from disk and check its validity. To initialize a new +repository in the given filepath, use ostree_repo_create() instead.

    +

    To store content in the repo, first start a transaction with +ostree_repo_prepare_transaction(). Then create a +OstreeMutableTree, and apply functions such as +ostree_repo_write_directory_to_mtree() to traverse a physical +filesystem and write content, possibly multiple times.

    +

    Once the OstreeMutableTree is complete, write all of its metadata +with ostree_repo_write_mtree(), and finally create a commit with +ostree_repo_write_commit().

    +
    +

    Collection IDs

    +

    A collection ID is a globally unique identifier which, if set, is used to +identify refs from a repository which are mirrored elsewhere, such as in +mirror repositories or peer to peer networks.

    +

    This is separate from the collection-id configuration key for a remote, which +is used to store the collection ID of the repository that remote points to.

    +

    The collection ID should only be set on an OstreeRepo if it is the canonical +collection for some refs.

    +

    A collection ID must be a reverse DNS name, where the domain name is under the +control of the curator of the collection, so they can demonstrate ownership +of the collection. The later elements in the reverse DNS name can be used to +disambiguate between multiple collections from the same curator. For example, +org.exampleos.Main and org.exampleos.Apps. For the complete format of +collection IDs, see ostree_validate_collection_id().

    +
    +
    +
    +

    Functions

    +
    +

    ostree_repo_mode_from_string ()

    +
    gboolean
    +ostree_repo_mode_from_string (const char *mode,
    +                              OstreeRepoMode *out_mode,
    +                              GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    mode

    a repo mode as a string

     

    out_mode

    the corresponding OstreeRepoMode.

    [out]

    error

    a GError if the string is not a valid mode

     
    +
    +
    +
    +
    +

    ostree_repo_open_at ()

    +
    OstreeRepo *
    +ostree_repo_open_at (int dfd,
    +                     const char *path,
    +                     GCancellable *cancellable,
    +                     GError **error);
    +

    This combines ostree_repo_new() (but using fd-relative access) with +ostree_repo_open(). Use this when you know you should be operating on an +already extant repository. If you want to create one, use ostree_repo_create_at().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    dfd

    Directory fd

     

    path

    Path

     
    +
    +
    +

    Returns

    +

    An accessor object for an OSTree repository located at dfd ++ path +.

    +

    [transfer full]

    +
    +

    Since: 2017.10

    +
    +
    +
    +

    ostree_repo_new ()

    +
    OstreeRepo *
    +ostree_repo_new (GFile *path);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    path

    Path to a repository

     
    +
    +
    +

    Returns

    +

    An accessor object for an OSTree repository located at path +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_new_for_sysroot_path ()

    +
    OstreeRepo *
    +ostree_repo_new_for_sysroot_path (GFile *repo_path,
    +                                  GFile *sysroot_path);
    +

    Creates a new OstreeRepo instance, taking the system root path explicitly +instead of assuming "/".

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    repo_path

    Path to a repository

     

    sysroot_path

    Path to the system root

     
    +
    +
    +

    Returns

    +

    An accessor object for the OSTree repository located at repo_path +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_new_default ()

    +
    OstreeRepo *
    +ostree_repo_new_default (void);
    +

    If the current working directory appears to be an OSTree +repository, create a new OstreeRepo object for accessing it. +Otherwise use the path in the OSTREE_REPO environment variable +(if defined) or else the default system repository located at +/ostree/repo.

    +
    +

    Returns

    +

    An accessor object for an OSTree repository located at /ostree/repo.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_open ()

    +
    gboolean
    +ostree_repo_open (OstreeRepo *self,
    +                  GCancellable *cancellable,
    +                  GError **error);
    +
    +
    +
    +

    ostree_repo_set_disable_fsync ()

    +
    void
    +ostree_repo_set_disable_fsync (OstreeRepo *self,
    +                               gboolean disable_fsync);
    +

    Disable requests to fsync() to stable storage during commits. This +option should only be used by build system tools which are creating +disposable virtual machines, or have higher level mechanisms for +ensuring data consistency.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    disable_fsync

    If TRUE, do not fsync

     
    +
    +
    +
    +
    +

    ostree_repo_get_disable_fsync ()

    +
    gboolean
    +ostree_repo_get_disable_fsync (OstreeRepo *self);
    +

    For more information see ostree_repo_set_disable_fsync().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    An OstreeRepo

     
    +
    +
    +

    Returns

    +

    Whether or not fsync() is enabled for this repo.

    +
    +
    +
    +
    +

    ostree_repo_is_system ()

    +
    gboolean
    +ostree_repo_is_system (OstreeRepo *repo);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    repo

    Repository

     
    +
    +
    +

    Returns

    +

    TRUE if this repository is the root-owned system global repository

    +
    +
    +
    +
    +

    ostree_repo_is_writable ()

    +
    gboolean
    +ostree_repo_is_writable (OstreeRepo *self,
    +                         GError **error);
    +

    Returns whether the repository is writable by the current user. +If the repository is not writable, the error + indicates why.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Repo

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE if this repository is writable

    +
    +
    +
    +
    +

    ostree_repo_create_at ()

    +
    OstreeRepo *
    +ostree_repo_create_at (int dfd,
    +                       const char *path,
    +                       OstreeRepoMode mode,
    +                       GVariant *options,
    +                       GCancellable *cancellable,
    +                       GError **error);
    +

    This is a file-descriptor relative version of ostree_repo_create(). +Create the underlying structure on disk for the repository, and call +ostree_repo_open_at() on the result, preparing it for use.

    +

    If a repository already exists at dfd + + path + (defined by an objects/ +subdirectory existing), then this function will simply call +ostree_repo_open_at(). In other words, this function cannot be used to change +the mode or configuration (repo/config) of an existing repo.

    +

    The options + dict may contain:

    +
    • collection-id: s: Set as collection ID in repo/config (Since 2017.9)

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    dfd

    Directory fd

     

    path

    Path

     

    mode

    The mode to store the repository in

     

    options

    a{sv}: See below for accepted keys.

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    A new OSTree repository reference.

    +

    [transfer full]

    +
    +

    Since: 2017.10

    +
    +
    +
    +

    ostree_repo_create ()

    +
    gboolean
    +ostree_repo_create (OstreeRepo *self,
    +                    OstreeRepoMode mode,
    +                    GCancellable *cancellable,
    +                    GError **error);
    +

    Create the underlying structure on disk for the repository, and call +ostree_repo_open() on the result, preparing it for use.

    +

    Since version 2016.8, this function will succeed on an existing +repository, and finish creating any necessary files in a partially +created repository. However, this function cannot change the mode +of an existing repository, and will silently ignore an attempt to +do so.

    +

    Since 2017.9, "existing repository" is defined by the existence of an +objects subdirectory.

    +

    This function predates ostree_repo_create_at(). It is an error to call +this function on a repository initialized via ostree_repo_open_at().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    mode

    The mode to store the repository in

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_get_collection_id ()

    +
    const gchar *
    +ostree_repo_get_collection_id (OstreeRepo *self);
    +

    Get the collection ID of this repository. See collection IDs.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeRepo

     
    +
    +
    +

    Returns

    +

    collection ID for the repository.

    +

    [nullable]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_get_bootloader ()

    +
    const gchar *
    +ostree_repo_get_bootloader (OstreeRepo *self);
    +

    Get the bootloader configured. See the documentation for the +"sysroot.bootloader" config key.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeRepo

     
    +
    +
    +

    Returns

    +

    bootloader configuration for the sysroot.

    +

    [transfer none]

    +
    +

    Since: 2019.2

    +
    +
    +
    +

    ostree_repo_get_path ()

    +
    GFile *
    +ostree_repo_get_path (OstreeRepo *self);
    +

    Note that since the introduction of ostree_repo_open_at(), this function may +return a process-specific path in /proc if the repository was created using +that API. In general, you should avoid use of this API.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Repo

     
    +
    +
    +

    Returns

    +

    Path to repo.

    +

    [transfer none]

    +
    +
    +
    +
    +

    ostree_repo_get_mode ()

    +
    OstreeRepoMode
    +ostree_repo_get_mode (OstreeRepo *self);
    +
    +
    +
    +

    ostree_repo_get_min_free_space_bytes ()

    +
    gboolean
    +ostree_repo_get_min_free_space_bytes (OstreeRepo *self,
    +                                      guint64 *out_reserved_bytes,
    +                                      GError **error);
    +

    Determine the number of bytes of free disk space that are reserved according +to the repo config and return that number in out_reserved_bytes +. See the +documentation for the core.min-free-space-size and +core.min-free-space-percent repo config options.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    out_reserved_bytes

    Location to store the result.

    [out]

    error

    Return location for a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise.

    +
    +

    Since: 2018.9

    +
    +
    +
    +

    ostree_repo_get_config ()

    +
    GKeyFile *
    +ostree_repo_get_config (OstreeRepo *self);
    +
    +

    Returns

    +

    The repository configuration; do not modify.

    +

    [transfer none]

    +
    +
    +
    +
    +

    ostree_repo_get_dfd ()

    +
    int
    +ostree_repo_get_dfd (OstreeRepo *self);
    +

    In some cases it's useful for applications to access the repository +directly; for example, writing content into repo/tmp ensures it's +on the same filesystem. Another case is detecting the mtime on the +repository (to see whether a ref was written).

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Repo

     
    +
    +
    +

    Returns

    +

    File descriptor for repository root - owned by self +

    +
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_repo_get_default_repo_finders ()

    +
    const gchar *const *
    +ostree_repo_get_default_repo_finders (OstreeRepo *self);
    +

    Get the set of default repo finders configured. See the documentation for +the "core.default-repo-finders" config key.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeRepo

     
    +
    +
    +

    Returns

    +

    NULL-terminated array of strings.

    +

    [array zero-terminated=1][element-type utf8]

    +
    +

    Since: 2018.9

    +
    +
    +
    +

    ostree_repo_lock_pop ()

    +
    gboolean
    +ostree_repo_lock_pop (OstreeRepo *self,
    +                      OstreeRepoLockType lock_type,
    +                      GCancellable *cancellable,
    +                      GError **error);
    +

    Release a lock of type lock_type + from the lock state. If the lock state +becomes empty, the repository is unlocked. Otherwise, the lock state only +changes when transitioning from an exclusive lock back to a shared lock. The +requested lock_type + must be the same type that was requested in the call to +ostree_repo_lock_push(). It is a programmer error if these do not match and +the program may abort if the lock would reach an invalid state.

    +

    ostree_repo_lock_pop() waits for the lock depending on the repository's +lock-timeout-secs configuration. When lock-timeout-secs is -1, a blocking lock is +attempted. Otherwise, the lock is removed non-blocking and +ostree_repo_lock_pop() will sleep synchronously up to lock-timeout-secs seconds +attempting to remove the lock. If the lock cannot be removed within the +timeout, a G_IO_ERROR_WOULD_BLOCK error is returned.

    +

    If self + is not writable by the user, then no unlocking is attempted and +TRUE is returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    a OstreeRepo

     

    lock_type

    the type of lock to release

     

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, otherwise FALSE with error +set

    +
    +

    Since: 2021.3

    +
    +
    +
    +

    ostree_repo_lock_push ()

    +
    gboolean
    +ostree_repo_lock_push (OstreeRepo *self,
    +                       OstreeRepoLockType lock_type,
    +                       GCancellable *cancellable,
    +                       GError **error);
    +

    Takes a lock on the repository and adds it to the lock state. If lock_type + +is OSTREE_REPO_LOCK_SHARED, a shared lock is taken. If lock_type + is +OSTREE_REPO_LOCK_EXCLUSIVE, an exclusive lock is taken. The actual lock +state is only changed when locking a previously unlocked repository or +upgrading the lock from shared to exclusive. If the requested lock type is +unchanged or would represent a downgrade (exclusive to shared), the lock +state is not changed.

    +

    ostree_repo_lock_push() waits for the lock depending on the repository's +lock-timeout-secs configuration. When lock-timeout-secs is -1, a blocking lock is +attempted. Otherwise, the lock is taken non-blocking and +ostree_repo_lock_push() will sleep synchronously up to lock-timeout-secs seconds +attempting to acquire the lock. If the lock cannot be acquired within the +timeout, a G_IO_ERROR_WOULD_BLOCK error is returned.

    +

    If self + is not writable by the user, then no locking is attempted and +TRUE is returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    a OstreeRepo

     

    lock_type

    the type of lock to acquire

     

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, otherwise FALSE with error +set

    +
    +

    Since: 2021.3

    +
    +
    +
    +

    ostree_repo_auto_lock_push ()

    +
    OstreeRepoAutoLock *
    +ostree_repo_auto_lock_push (OstreeRepo *self,
    +                            OstreeRepoLockType lock_type,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Like ostree_repo_lock_push(), but for usage with OstreeRepoAutoLock. The +intended usage is to declare the OstreeRepoAutoLock with g_autoptr() so +that ostree_repo_auto_lock_cleanup() is called when it goes out of scope. +This will automatically release the lock if it was acquired successfully.

    +
    + + + + + + + +
    1
    +2
    +3
    +4
    g_autoptr(OstreeRepoAutoLock) lock = NULL;
    +lock = ostree_repo_auto_lock_push (repo, lock_type, cancellable, error);
    +if (!lock)
    +  return FALSE;
    +
    + +

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    a OstreeRepo

     

    lock_type

    the type of lock to acquire

     

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    self +on success, otherwise NULL with error +set

    +
    +

    Since: 2021.3

    +
    +
    +
    +

    ostree_repo_auto_lock_cleanup ()

    +
    void
    +ostree_repo_auto_lock_cleanup (OstreeRepoAutoLock *lock);
    +

    A cleanup handler for use with ostree_repo_auto_lock_push(). If lock + is +not NULL, ostree_repo_lock_pop() will be called on it. If +ostree_repo_lock_pop() fails, a critical warning will be emitted.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + +

    lock

    a OstreeRepoAutoLock

     
    +
    +

    Since: 2021.3

    +
    +
    +
    +

    ostree_repo_hash ()

    +
    guint
    +ostree_repo_hash (OstreeRepo *self);
    +

    Calculate a hash value for the given open repository, suitable for use when +putting it into a hash table. It is an error to call this on an OstreeRepo +which is not yet open, as a persistent hash value cannot be calculated until +the repository is open and the inode of its root directory has been loaded.

    +

    This function does no I/O.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeRepo

     
    +
    +
    +

    Returns

    +

    hash value for the OstreeRepo

    +
    +

    Since: 2017.12

    +
    +
    +
    +

    ostree_repo_equal ()

    +
    gboolean
    +ostree_repo_equal (OstreeRepo *a,
    +                   OstreeRepo *b);
    +

    Check whether two opened repositories are the same on disk: if their root +directories are the same inode. If a + or b + are not open yet (due to +ostree_repo_open() not being called on them yet), FALSE will be returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    a

    an OstreeRepo

     

    b

    an OstreeRepo

     
    +
    +
    +

    Returns

    +

    TRUE if a +and b +are the same repository on disk, FALSE otherwise

    +
    +

    Since: 2017.12

    +
    +
    +
    +

    ostree_repo_copy_config ()

    +
    GKeyFile *
    +ostree_repo_copy_config (OstreeRepo *self);
    +
    +

    Returns

    +

    A newly-allocated copy of the repository config.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_remote_add ()

    +
    gboolean
    +ostree_repo_remote_add (OstreeRepo *self,
    +                        const char *name,
    +                        const char *url,
    +                        GVariant *options,
    +                        GCancellable *cancellable,
    +                        GError **error);
    +

    Create a new remote named name + pointing to url +. If options + is +provided, then it will be mapped to GKeyFile entries, where the +GVariant dictionary key is an option string, and the value is +mapped as follows:

    +
      +
    • s: g_key_file_set_string()

    • +
    • b: g_key_file_set_boolean()

    • +
    • as: g_key_file_set_string_list()

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    name

    Name of remote

     

    url

    URL for remote (if URL begins with metalink=, it will be used as such).

    [allow-none]

    options

    GVariant of type a{sv}.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_remote_delete ()

    +
    gboolean
    +ostree_repo_remote_delete (OstreeRepo *self,
    +                           const char *name,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Delete the remote named name +. It is an error if the provided +remote does not exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    name

    Name of remote

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_remote_change ()

    +
    gboolean
    +ostree_repo_remote_change (OstreeRepo *self,
    +                           GFile *sysroot,
    +                           OstreeRepoRemoteChange changeop,
    +                           const char *name,
    +                           const char *url,
    +                           GVariant *options,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    A combined function handling the equivalent of +ostree_repo_remote_add(), ostree_repo_remote_delete(), with more +options.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    sysroot

    System root.

    [allow-none]

    changeop

    Operation to perform

     

    name

    Name of remote

     

    url

    URL for remote (if URL begins with metalink=, it will be used as such).

    [allow-none]

    options

    GVariant of type a{sv}.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_remote_list ()

    +
    char **
    +ostree_repo_remote_list (OstreeRepo *self,
    +                         guint *out_n_remotes);
    +

    List available remote names in an OstreeRepo. Remote names are sorted +alphabetically. If no remotes are available the function returns NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Repo

     

    out_n_remotes

    Number of remotes available.

    [out][allow-none]
    +
    +
    +

    Returns

    +

    a NULL-terminated +array of remote names.

    +

    [array length=out_n_remotes][transfer full]

    +
    +
    +
    +
    +

    ostree_repo_remote_list_collection_refs ()

    +
    gboolean
    +ostree_repo_remote_list_collection_refs
    +                               (OstreeRepo *self,
    +                                const char *remote_name,
    +                                GHashTable **out_all_refs,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    List refs advertised by remote_name +, including refs which are part of +collections. If the repository at remote_name + has a collection ID set, its +refs will be returned with that collection ID; otherwise, they will be returned +with a NULL collection ID in each OstreeCollectionRef key in out_all_refs +. +Any refs for other collections stored in the repository will also be returned. +No filtering is performed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of the remote.

     

    out_all_refs

    Mapping from collection–ref to checksum.

    [out][element-type OstreeCollectionRef utf8][transfer container]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_remote_get_url ()

    +
    gboolean
    +ostree_repo_remote_get_url (OstreeRepo *self,
    +                            const char *name,
    +                            char **out_url,
    +                            GError **error);
    +

    Return the URL of the remote named name + through out_url +. It is an +error if the provided remote does not exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    name

    Name of remote

     

    out_url

    Remote's URL.

    [out][optional]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_repo_remote_get_gpg_verify ()

    +
    gboolean
    +ostree_repo_remote_get_gpg_verify (OstreeRepo *self,
    +                                   const char *name,
    +                                   gboolean *out_gpg_verify,
    +                                   GError **error);
    +

    Return whether GPG verification is enabled for the remote named name + +through out_gpg_verify +. It is an error if the provided remote does +not exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    name

    Name of remote

     

    out_gpg_verify

    Remote's GPG option.

    [out][optional]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_repo_remote_get_gpg_verify_summary ()

    +
    gboolean
    +ostree_repo_remote_get_gpg_verify_summary
    +                               (OstreeRepo *self,
    +                                const char *name,
    +                                gboolean *out_gpg_verify_summary,
    +                                GError **error);
    +

    Return whether GPG verification of the summary is enabled for the remote +named name + through out_gpg_verify_summary +. It is an error if the provided +remote does not exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    name

    Name of remote

     

    out_gpg_verify_summary

    Remote's GPG option.

    [out][allow-none]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_repo_remote_get_gpg_keys ()

    +
    gboolean
    +ostree_repo_remote_get_gpg_keys (OstreeRepo *self,
    +                                 const char *name,
    +                                 const char *const *key_ids,
    +                                 GPtrArray **out_keys,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Enumerate the trusted GPG keys for the remote name +. If name + is +NULL, the global GPG keys will be returned. The keys will be +returned in the out_keys + GPtrArray. Each element in the array is a +GVariant of format OSTREE_GPG_KEY_GVARIANT_FORMAT. The key_ids + +array can be used to limit which keys are included. If key_ids + is +NULL, then all keys are included.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    name

    name of the remote or NULL.

    [nullable]

    key_ids

    a NULL-terminated array of GPG key IDs to include, or NULL.

    [array zero-terminated=1][element-type utf8][nullable]

    out_keys

    return location for a GPtrArray of the remote's trusted GPG keys, or +NULL.

    [out][optional][element-type GVariant][transfer container]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    TRUE if the GPG keys could be enumerated, FALSE otherwise

    +
    +

    Since: 2021.4

    +
    +
    +
    +

    ostree_repo_remote_gpg_import ()

    +
    gboolean
    +ostree_repo_remote_gpg_import (OstreeRepo *self,
    +                               const char *name,
    +                               GInputStream *source_stream,
    +                               const char *const *key_ids,
    +                               guint *out_imported,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    Imports one or more GPG keys from the open source_stream +, or from the +user's personal keyring if source_stream + is NULL. The key_ids + array +can optionally restrict which keys are imported. If key_ids + is NULL, +then all keys are imported.

    +

    The imported keys will be used to conduct GPG verification when pulling +from the remote named name +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    name

    name of a remote

     

    source_stream

    a GInputStream, or NULL.

    [nullable]

    key_ids

    a NULL-terminated array of +GPG key IDs, or NULL.

    [array zero-terminated=1][element-type utf8][nullable]

    out_imported

    return location for the number of imported +keys, or NULL.

    [out][optional]

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_repo_remote_fetch_summary ()

    +
    gboolean
    +ostree_repo_remote_fetch_summary (OstreeRepo *self,
    +                                  const char *name,
    +                                  GBytes **out_summary,
    +                                  GBytes **out_signatures,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Tries to fetch the summary file and any GPG signatures on the summary file +over HTTP, and returns the binary data in out_summary + and out_signatures + +respectively.

    +

    If no summary file exists on the remote server, out_summary + is set to +NULL +. Likewise if the summary file is not signed, out_signatures + is +set to NULL +. In either case the function still returns TRUE.

    +

    This method does not verify the signature of the downloaded summary file. +Use ostree_repo_verify_summary() for that.

    +

    Parse the summary data into a GVariant using g_variant_new_from_bytes() +with OSTREE_SUMMARY_GVARIANT_FORMAT as the format string.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    name

    name of a remote

     

    out_summary

    return location for raw summary data, or +NULL.

    [out][optional]

    out_signatures

    return location for raw summary +signature data, or NULL.

    [out][optional]

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +
    +
    +
    +

    ostree_repo_remote_fetch_summary_with_options ()

    +
    gboolean
    +ostree_repo_remote_fetch_summary_with_options
    +                               (OstreeRepo *self,
    +                                const char *name,
    +                                GVariant *options,
    +                                GBytes **out_summary,
    +                                GBytes **out_signatures,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Like ostree_repo_remote_fetch_summary(), but supports an extensible set of flags. +The following are currently defined:

    +
      +
    • override-url (s): Fetch summary from this URL if remote specifies no metalink in options

    • +
    • http-headers (a(ss)): Additional headers to add to all HTTP requests

    • +
    • append-user-agent (s): Additional string to append to the user agent

    • +
    • n-network-retries (u): Number of times to retry each download on receiving +a transient network error, such as a socket timeout; default is 5, 0 +means return errors without retrying

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    name

    name of a remote

     

    options

    A GVariant a{sv} with an extensible set of flags.

    [nullable]

    out_summary

    return location for raw summary data, or NULL.

    [out][optional]

    out_signatures

    return location for raw summary signature +data, or NULL.

    [out][optional]

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2016.6

    +
    +
    +
    +

    ostree_repo_reload_config ()

    +
    gboolean
    +ostree_repo_reload_config (OstreeRepo *self,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    By default, an OstreeRepo will cache the remote configuration and its +own repo/config data. This API can be used to reload it.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    repo

     

    cancellable

    cancellable

     

    error

    error

     
    +
    +

    Since: 2017.2

    +
    +
    +
    +

    ostree_repo_get_remote_boolean_option ()

    +
    gboolean
    +ostree_repo_get_remote_boolean_option (OstreeRepo *self,
    +                                       const char *remote_name,
    +                                       const char *option_name,
    +                                       gboolean default_value,
    +                                       gboolean *out_value,
    +                                       GError **error);
    +

    OSTree remotes are represented by keyfile groups, formatted like: +[remote "remotename"]. This function returns a value named option_name + +underneath that group, and returns it as a boolean. +If the option is not set, out_value + will be set to default_value +. If an +error is returned, out_value + will be set to FALSE.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    A OstreeRepo

     

    remote_name

    Name

     

    option_name

    Option

     

    default_value

    Value returned if option_name +is not present

     

    out_value

    (out) : location to store the result.

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, otherwise FALSE with error +set

    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_repo_get_remote_list_option ()

    +
    gboolean
    +ostree_repo_get_remote_list_option (OstreeRepo *self,
    +                                    const char *remote_name,
    +                                    const char *option_name,
    +                                    char ***out_value,
    +                                    GError **error);
    +

    OSTree remotes are represented by keyfile groups, formatted like: +[remote "remotename"]. This function returns a value named option_name + +underneath that group, and returns it as a zero terminated array of strings. +If the option is not set, or if an error is returned, out_value + will be set +to NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    A OstreeRepo

     

    remote_name

    Name

     

    option_name

    Option

     

    out_value

    location to store the list +of strings. The list should be freed with +g_strfreev().

    [out][array zero-terminated=1]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, otherwise FALSE with error +set

    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_repo_get_remote_option ()

    +
    gboolean
    +ostree_repo_get_remote_option (OstreeRepo *self,
    +                               const char *remote_name,
    +                               const char *option_name,
    +                               const char *default_value,
    +                               char **out_value,
    +                               GError **error);
    +

    OSTree remotes are represented by keyfile groups, formatted like: +[remote "remotename"]. This function returns a value named option_name + +underneath that group, or default_value + if the remote exists but not the +option name. If an error is returned, out_value + will be set to NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    A OstreeRepo

     

    remote_name

    Name

     

    option_name

    Option

     

    default_value

    Value returned if option_name +is not present.

    [nullable]

    out_value

    Return location for value.

    [out][nullable]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, otherwise FALSE with error +set

    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_repo_get_parent ()

    +
    OstreeRepo *
    +ostree_repo_get_parent (OstreeRepo *self);
    +

    Before this function can be used, ostree_repo_init() must have been +called.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Repo

     
    +
    +
    +

    Returns

    +

    Parent repository, or NULL if none.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_repo_write_config ()

    +
    gboolean
    +ostree_repo_write_config (OstreeRepo *self,
    +                          GKeyFile *new_config,
    +                          GError **error);
    +

    Save new_config + in place of this repository's config file.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    new_config

    Overwrite the config file with this data

     

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_repo_scan_hardlinks ()

    +
    gboolean
    +ostree_repo_scan_hardlinks (OstreeRepo *self,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    This function is deprecated in favor of using ostree_repo_devino_cache_new(), +which allows a precise mapping to be built up between hardlink checkout files +and their checksums between ostree_repo_checkout_at() and +ostree_repo_write_directory_to_mtree().

    +

    When invoking ostree_repo_write_directory_to_mtree(), it has to compute the +checksum of all files. If your commit contains hardlinks from a checkout, +this functions builds a mapping of device numbers and inodes to their +checksum.

    +

    There is an upfront cost to creating this mapping, as this will scan the +entire objects directory. If your commit is composed of mostly hardlinks to +existing ostree objects, then this will speed up considerably, so call it +before you call ostree_repo_write_directory_to_mtree() or similar. However, +ostree_repo_devino_cache_new() is better as it avoids scanning all objects.

    +

    Multithreading: This function is *not* MT safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_prepare_transaction ()

    +
    gboolean
    +ostree_repo_prepare_transaction (OstreeRepo *self,
    +                                 gboolean *out_transaction_resume,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Starts or resumes a transaction. In order to write to a repo, you +need to start a transaction. You can complete the transaction with +ostree_repo_commit_transaction(), or abort the transaction with +ostree_repo_abort_transaction().

    +

    Currently, transactions may result in partial commits or data in the target +repository if interrupted during ostree_repo_commit_transaction(), and +further writing refs is also not currently atomic.

    +

    There can be at most one transaction active on a repo at a time per instance +of OstreeRepo; however, it is safe to have multiple threads writing objects +on a single OstreeRepo instance as long as their lifetime is bounded by the +transaction.

    +

    Locking: Acquires a shared lock; release via commit or abort +Multithreading: This function is *not* MT safe; only one transaction can be +active at a time.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    out_transaction_resume

    Whether this transaction +is resuming from a previous one. This is a legacy state, now OSTree +pulls use per-commit state/.commitpartial files.

    [allow-none][out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_commit_transaction ()

    +
    gboolean
    +ostree_repo_commit_transaction (OstreeRepo *self,
    +                                OstreeRepoTransactionStats *out_stats,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Complete the transaction. Any refs set with +ostree_repo_transaction_set_ref() or +ostree_repo_transaction_set_refspec() will be written out.

    +

    Note that if multiple threads are performing writes, all such threads must +have terminated before this function is invoked.

    +

    Locking: Releases shared lock acquired by ostree_repo_prepare_transaction() +Multithreading: This function is *not* MT safe; only one transaction can be +active at a time.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    out_stats

    A set of statistics of things +that happened during this transaction.

    [allow-none][out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_abort_transaction ()

    +
    gboolean
    +ostree_repo_abort_transaction (OstreeRepo *self,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    Abort the active transaction; any staged objects and ref changes will be +discarded. You *must* invoke this if you have chosen not to invoke +ostree_repo_commit_transaction(). Calling this function when not in a +transaction will do nothing and return successfully.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_transaction_set_refspec ()

    +
    void
    +ostree_repo_transaction_set_refspec (OstreeRepo *self,
    +                                     const char *refspec,
    +                                     const char *checksum);
    +

    Like ostree_repo_transaction_set_ref(), but takes concatenated +refspec + format as input instead of separate remote and name +arguments.

    +

    Multithreading: Since v2017.15 this function is MT safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    refspec

    The refspec to write

     

    checksum

    The checksum to point it to.

    [nullable]
    +
    +
    +
    +
    +

    ostree_repo_transaction_set_collection_ref ()

    +
    void
    +ostree_repo_transaction_set_collection_ref
    +                               (OstreeRepo *self,
    +                                const OstreeCollectionRef *ref,
    +                                const char *checksum);
    +

    If checksum + is not NULL, then record it as the target of local ref named +ref +.

    +

    Otherwise, if checksum + is NULL, then record that the ref should +be deleted.

    +

    The change will not be written out immediately, but when the transaction +is completed with ostree_repo_commit_transaction(). If the transaction +is instead aborted with ostree_repo_abort_transaction(), no changes will +be made to the repository.

    +

    Multithreading: Since v2017.15 this function is MT safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    ref

    The collection–ref to write

     

    checksum

    The checksum to point it to.

    [nullable]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_transaction_set_ref ()

    +
    void
    +ostree_repo_transaction_set_ref (OstreeRepo *self,
    +                                 const char *remote,
    +                                 const char *ref,
    +                                 const char *checksum);
    +

    If checksum + is not NULL, then record it as the target of ref named +ref +; if remote + is provided, the ref will appear to originate from that +remote.

    +

    Otherwise, if checksum + is NULL, then record that the ref should +be deleted.

    +

    The change will be written when the transaction is completed with +ostree_repo_commit_transaction(); that function takes care of writing all of +the objects (such as the commit referred to by checksum +) before updating the +refs. If the transaction is instead aborted with +ostree_repo_abort_transaction(), no changes to the ref will be made to the +repository.

    +

    Note however that currently writing *multiple* refs is not truly atomic; if +the process or system is terminated during +ostree_repo_commit_transaction(), it is possible that just some of the refs +will have been updated. Your application should take care to handle this +case.

    +

    Multithreading: Since v2017.15 this function is MT safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    remote

    A remote for the ref.

    [allow-none]

    ref

    The ref to write

     

    checksum

    The checksum to point it to.

    [nullable]
    +
    +
    +
    +
    +

    ostree_repo_set_ref_immediate ()

    +
    gboolean
    +ostree_repo_set_ref_immediate (OstreeRepo *self,
    +                               const char *remote,
    +                               const char *ref,
    +                               const char *checksum,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    This is like ostree_repo_transaction_set_ref(), except it may be +invoked outside of a transaction. This is presently safe for the +case where we're creating or overwriting an existing ref.

    +

    Multithreading: This function is MT safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    remote

    A remote for the ref.

    [allow-none]

    ref

    The ref to write

     

    checksum

    The checksum to point it to, or NULL to unset.

    [allow-none]

    cancellable

    GCancellable

     

    error

    GError

     
    +
    +
    +
    +
    +

    ostree_repo_set_alias_ref_immediate ()

    +
    gboolean
    +ostree_repo_set_alias_ref_immediate (OstreeRepo *self,
    +                                     const char *remote,
    +                                     const char *ref,
    +                                     const char *target,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Like ostree_repo_set_ref_immediate(), but creates an alias.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    remote

    A remote for the ref.

    [allow-none]

    ref

    The ref to write

     

    target

    The ref target to point it to, or NULL to unset.

    [allow-none]

    cancellable

    GCancellable

     

    error

    GError

     
    +
    +

    Since: 2017.10

    +
    +
    +
    +

    ostree_repo_set_cache_dir ()

    +
    gboolean
    +ostree_repo_set_cache_dir (OstreeRepo *self,
    +                           int dfd,
    +                           const char *path,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Set a custom location for the cache directory used for e.g. +per-remote summary caches. Setting this manually is useful when +doing operations on a system repo as a user because you don't have +write permissions in the repo, where the cache is normally stored.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    dfd

    directory fd

     

    path

    subpath in dfd +

     

    cancellable

    a GCancellable

     

    error

    a GError

     
    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_repo_set_collection_id ()

    +
    gboolean
    +ostree_repo_set_collection_id (OstreeRepo *self,
    +                               const gchar *collection_id,
    +                               GError **error);
    +

    Set or clear the collection ID of this repository. See collection IDs. +The update will be made in memory, but must be written out to the repository +configuration on disk using ostree_repo_write_config().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    collection_id

    new collection ID, or NULL to unset it.

    [nullable]

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_set_collection_ref_immediate ()

    +
    gboolean
    +ostree_repo_set_collection_ref_immediate
    +                               (OstreeRepo *self,
    +                                const OstreeCollectionRef *ref,
    +                                const char *checksum,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    This is like ostree_repo_transaction_set_collection_ref(), except it may be +invoked outside of a transaction. This is presently safe for the +case where we're creating or overwriting an existing ref.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    ref

    The collection–ref to write

     

    checksum

    The checksum to point it to, or NULL to unset.

    [nullable]

    cancellable

    GCancellable

     

    error

    GError

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_sign_delta ()

    +
    gboolean
    +ostree_repo_sign_delta (OstreeRepo *self,
    +                        const gchar *from_commit,
    +                        const gchar *to_commit,
    +                        const gchar *key_id,
    +                        const gchar *homedir,
    +                        GCancellable *cancellable,
    +                        GError **error);
    +

    This function is deprecated, sign the summary file instead. +Add a GPG signature to a static delta.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    from_commit

    From commit

     

    to_commit

    To commit

     

    key_id

    key id

     

    homedir

    homedir

     

    cancellable

    cancellable

     

    error

    error

     
    +
    +
    +
    +
    +

    ostree_repo_has_object ()

    +
    gboolean
    +ostree_repo_has_object (OstreeRepo *self,
    +                        OstreeObjectType objtype,
    +                        const char *checksum,
    +                        gboolean *out_have_object,
    +                        GCancellable *cancellable,
    +                        GError **error);
    +

    Set out_have_object + to TRUE if self + contains the given object; +FALSE otherwise.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    checksum

    ASCII SHA256 checksum

     

    out_have_object

    TRUE if repository contains object.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    FALSE if an unexpected error occurred, TRUE otherwise

    +
    +
    +
    +
    +

    ostree_repo_mark_commit_partial ()

    +
    gboolean
    +ostree_repo_mark_commit_partial (OstreeRepo *self,
    +                                 const char *checksum,
    +                                 gboolean is_partial,
    +                                 GError **error);
    +

    Commits in the "partial" state do not have all their child objects +written. This occurs in various situations, such as during a pull, +but also if a "subpath" pull is used, as well as "commit only" +pulls.

    +

    This function is used by ostree_repo_pull_with_options(); you +should use this if you are implementing a different type of transport.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    Commit SHA-256

     

    is_partial

    Whether or not this commit is partial

     

    error

    Error

     
    +
    +

    Since: 2017.15

    +
    +
    +
    +

    ostree_repo_mark_commit_partial_reason ()

    +
    gboolean
    +ostree_repo_mark_commit_partial_reason
    +                               (OstreeRepo *self,
    +                                const char *checksum,
    +                                gboolean is_partial,
    +                                OstreeRepoCommitState in_state,
    +                                GError **error);
    +

    Allows the setting of a reason code for a partial commit. Presently +it only supports setting reason bitmask to +OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL, or +OSTREE_REPO_COMMIT_STATE_NORMAL. This will allow successive ostree +fsck operations to exit properly with an error code if the +repository has been truncated as a result of fsck trying to repair +it.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    Commit SHA-256

     

    is_partial

    Whether or not this commit is partial

     

    in_state

    Reason bitmask for partial commit

     

    error

    Error

     
    +
    +

    Since: 2019.4

    +
    +
    +
    +

    ostree_repo_write_metadata ()

    +
    gboolean
    +ostree_repo_write_metadata (OstreeRepo *self,
    +                            OstreeObjectType objtype,
    +                            const char *expected_checksum,
    +                            GVariant *object,
    +                            guchar **out_csum,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Store the metadata object object +. Return the checksum +as out_csum +.

    +

    If expected_checksum + is not NULL, verify it against the +computed checksum.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    expected_checksum

    If provided, validate content against this checksum.

    [nullable]

    object

    Metadata

     

    out_csum

    Binary checksum.

    [out][array fixed-size=32][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_metadata_async ()

    +
    void
    +ostree_repo_write_metadata_async (OstreeRepo *self,
    +                                  OstreeObjectType objtype,
    +                                  const char *expected_checksum,
    +                                  GVariant *object,
    +                                  GCancellable *cancellable,
    +                                  GAsyncReadyCallback callback,
    +                                  gpointer user_data);
    +

    Asynchronously store the metadata object variant +. If provided, +the checksum expected_checksum + will be verified.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    expected_checksum

    If provided, validate content against this checksum.

    [nullable]

    object

    Metadata

     

    cancellable

    Cancellable

     

    callback

    Invoked when metadata is writed

     

    user_data

    Data for callback +

     
    +
    +
    +
    +
    +

    ostree_repo_write_metadata_finish ()

    +
    gboolean
    +ostree_repo_write_metadata_finish (OstreeRepo *self,
    +                                   GAsyncResult *result,
    +                                   guchar **out_csum,
    +                                   GError **error);
    +

    Complete a call to ostree_repo_write_metadata_async().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    result

    Result

     

    out_csum

    Binary checksum value.

    [out][array fixed-size=32][element-type guint8]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_content ()

    +
    gboolean
    +ostree_repo_write_content (OstreeRepo *self,
    +                           const char *expected_checksum,
    +                           GInputStream *object_input,
    +                           guint64 length,
    +                           guchar **out_csum,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Store the content object streamed as object_input +, +with total length length +. The actual checksum will +be returned as out_csum +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    expected_checksum

    If provided, validate content against this checksum.

    [allow-none]

    object_input

    Content object stream

     

    length

    Length of object_input +

     

    out_csum

    Binary checksum.

    [out][array fixed-size=32][optional][nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_regfile ()

    +
    OstreeContentWriter *
    +ostree_repo_write_regfile (OstreeRepo *self,
    +                           const char *expected_checksum,
    +                           guint32 uid,
    +                           guint32 gid,
    +                           guint32 mode,
    +                           guint64 content_len,
    +                           GVariant *xattrs,
    +                           GError **error);
    +

    Create an OstreeContentWriter that allows streaming output into +the repository.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo,

     

    expected_checksum

    Expected checksum (SHA-256 hex string).

    [allow-none]

    uid

    user id

     

    gid

    group id

     

    mode

    Unix file mode

     

    content_len

    Expected content length

     

    xattrs

    Extended attributes (GVariant type (ayay)).

    [allow-none]

    error

    Error

     
    +
    +
    +

    Returns

    +

    A new writer, or NULL on error.

    +

    [transfer full]

    +
    +

    Since: 2021.2

    +
    +
    +
    +

    ostree_repo_write_regfile_inline ()

    +
    char *
    +ostree_repo_write_regfile_inline (OstreeRepo *self,
    +                                  const char *expected_checksum,
    +                                  guint32 uid,
    +                                  guint32 gid,
    +                                  guint32 mode,
    +                                  GVariant *xattrs,
    +                                  const guint8 *buf,
    +                                  gsize len,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Synchronously create a file object from the provided content. This API +is intended for small files where it is reasonable to buffer the entire +content in memory.

    +

    Unlike ostree_repo_write_content(), if expected_checksum + is provided, +this function will not check for the presence of the object beforehand.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    repo

     

    expected_checksum

    The expected checksum.

    [allow-none]

    uid

    User id

     

    gid

    Group id

     

    mode

    File mode

     

    xattrs

    Extended attributes, GVariant of type (ayay).

    [allow-none]

    buf

    File contents.

    [array length=len][element-type guint8]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    Checksum (as a hex string) of the committed file.

    +

    [transfer full]

    +
    +

    Since: 2021.2

    +
    +
    +
    +

    ostree_repo_write_symlink ()

    +
    char *
    +ostree_repo_write_symlink (OstreeRepo *self,
    +                           const char *expected_checksum,
    +                           guint32 uid,
    +                           guint32 gid,
    +                           GVariant *xattrs,
    +                           const char *symlink_target,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Synchronously create a symlink object.

    +

    Unlike ostree_repo_write_content(), if expected_checksum + is provided, +this function will not check for the presence of the object beforehand.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    repo

     

    expected_checksum

    The expected checksum.

    [allow-none]

    uid

    User id

     

    gid

    Group id

     

    xattrs

    Extended attributes, GVariant of type (ayay).

    [allow-none]

    symlink_target

    Target of the symbolic link

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    Checksum (as a hex string) of the committed file.

    +

    [transfer full]

    +
    +

    Since: 2021.2

    +
    +
    +
    +

    ostree_repo_write_metadata_trusted ()

    +
    gboolean
    +ostree_repo_write_metadata_trusted (OstreeRepo *self,
    +                                    OstreeObjectType objtype,
    +                                    const char *checksum,
    +                                    GVariant *variant,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Store the metadata object variant +; the provided checksum + is +trusted.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    checksum

    Store object with this ASCII SHA256 checksum

     

    variant

    Metadata object

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_metadata_stream_trusted ()

    +
    gboolean
    +ostree_repo_write_metadata_stream_trusted
    +                               (OstreeRepo *self,
    +                                OstreeObjectType objtype,
    +                                const char *checksum,
    +                                GInputStream *object_input,
    +                                guint64 length,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Store the metadata object variant +; the provided checksum + is +trusted.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    checksum

    Store object with this ASCII SHA256 checksum

     

    object_input

    Metadata object stream

     

    length

    Length, may be 0 for unknown

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_content_trusted ()

    +
    gboolean
    +ostree_repo_write_content_trusted (OstreeRepo *self,
    +                                   const char *checksum,
    +                                   GInputStream *object_input,
    +                                   guint64 length,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Store the content object streamed as object_input +, with total +length length +. The given checksum + will be treated as trusted.

    +

    This function should be used when importing file objects from local +disk, for example.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    Store content using this ASCII SHA256 checksum

     

    object_input

    Content stream

     

    length

    Length of object_input +

     

    cancellable

    Cancellable

     

    error

    Data for callback +

     
    +
    +
    +
    +
    +

    ostree_repo_write_content_async ()

    +
    void
    +ostree_repo_write_content_async (OstreeRepo *self,
    +                                 const char *expected_checksum,
    +                                 GInputStream *object,
    +                                 guint64 length,
    +                                 GCancellable *cancellable,
    +                                 GAsyncReadyCallback callback,
    +                                 gpointer user_data);
    +

    Asynchronously store the content object object +. If provided, the +checksum expected_checksum + will be verified.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    expected_checksum

    If provided, validate content against this checksum.

    [allow-none]

    object

    Input

     

    length

    Length of object +

     

    cancellable

    Cancellable

     

    callback

    Invoked when content is writed

     

    user_data

    User data for callback +

     
    +
    +
    +
    +
    +

    ostree_repo_write_content_finish ()

    +
    gboolean
    +ostree_repo_write_content_finish (OstreeRepo *self,
    +                                  GAsyncResult *result,
    +                                  guchar **out_csum,
    +                                  GError **error);
    +

    Completes an invocation of ostree_repo_write_content_async().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    a OstreeRepo

     

    result

    a GAsyncResult

     

    out_csum

    A binary SHA256 +checksum of the content object.

    [out][transfer full][optional]

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_repo_resolve_rev ()

    +
    gboolean
    +ostree_repo_resolve_rev (OstreeRepo *self,
    +                         const char *refspec,
    +                         gboolean allow_noent,
    +                         char **out_rev,
    +                         GError **error);
    +

    Look up the given refspec, returning the checksum it references in +the parameter out_rev +. Will fall back on remote directory if cannot +find the given refspec in local.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    refspec

    A refspec

     

    allow_noent

    Do not throw an error if refspec does not exist

     

    out_rev

    A checksum,or NULL if allow_noent +is true and it +does not exist.

    [out][nullable][transfer full]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_resolve_rev_ext ()

    +
    gboolean
    +ostree_repo_resolve_rev_ext (OstreeRepo *self,
    +                             const char *refspec,
    +                             gboolean allow_noent,
    +                             OstreeRepoResolveRevExtFlags flags,
    +                             char **out_rev,
    +                             GError **error);
    +

    Look up the given refspec, returning the checksum it references in +the parameter out_rev +. Differently from ostree_repo_resolve_rev(), +this will not fall back to searching through remote repos if a +local ref is specified but not found.

    +

    The flag OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY is implied so +using it has no effect.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    refspec

    A refspec

     

    allow_noent

    Do not throw an error if refspec does not exist

     

    flags

    Options controlling behavior

     

    out_rev

    A checksum,or NULL if allow_noent +is true and it +does not exist.

    [out][nullable][transfer full]

    error

    Error

     
    +
    +

    Since: 2016.7

    +
    +
    +
    +

    ostree_repo_list_refs ()

    +
    gboolean
    +ostree_repo_list_refs (OstreeRepo *self,
    +                       const char *refspec_prefix,
    +                       GHashTable **out_all_refs,
    +                       GCancellable *cancellable,
    +                       GError **error);
    +

    If refspec_prefix + is NULL, list all local and remote refspecs, +with their current values in out_all_refs +. Otherwise, only list +refspecs which have refspec_prefix + as a prefix.

    +

    out_all_refs + will be returned as a mapping from refspecs (including the +remote name) to checksums. If refspec_prefix + is non-NULL, it will be +removed as a prefix from the hash table keys.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    refspec_prefix

    Only list refs which match this prefix.

    [allow-none]

    out_all_refs

    Mapping from refspec to checksum.

    [out][element-type utf8 utf8][transfer container]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_list_refs_ext ()

    +
    gboolean
    +ostree_repo_list_refs_ext (OstreeRepo *self,
    +                           const char *refspec_prefix,
    +                           GHashTable **out_all_refs,
    +                           OstreeRepoListRefsExtFlags flags,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    If refspec_prefix + is NULL, list all local and remote refspecs, +with their current values in out_all_refs +. Otherwise, only list +refspecs which have refspec_prefix + as a prefix.

    +

    out_all_refs + will be returned as a mapping from refspecs (including the +remote name) to checksums. Differently from ostree_repo_list_refs(), the +refspec_prefix + will not be removed from the refspecs in the hash table.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    refspec_prefix

    Only list refs which match this prefix.

    [allow-none]

    out_all_refs

    Mapping from refspec to checksum.

    [out][element-type utf8 utf8][transfer container]

    flags

    Options controlling listing behavior

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_repo_list_collection_refs ()

    +
    gboolean
    +ostree_repo_list_collection_refs (OstreeRepo *self,
    +                                  const char *match_collection_id,
    +                                  GHashTable **out_all_refs,
    +                                  OstreeRepoListRefsExtFlags flags,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    List all local, mirrored, and remote refs, mapping them to the commit +checksums they currently point to in out_all_refs +. If match_collection_id + +is specified, the results will be limited to those with an equal collection +ID.

    +

    OstreeCollectionRefs are guaranteed to be returned with their collection ID +set to a non-NULL value; so no refs from refs/heads will be listed if no +collection ID is configured for the repository +(ostree_repo_get_collection_id()).

    +

    If you want to exclude refs from refs/remotes, use +OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES in flags +. Similarly use +OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS to exclude refs from +refs/mirrors.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    match_collection_id

    If non-NULL, only list refs from this collection.

    [nullable]

    out_all_refs

    Mapping from collection–ref to checksum.

    [out][element-type OstreeCollectionRef utf8][transfer container]

    flags

    Options controlling listing behavior

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_remote_list_refs ()

    +
    gboolean
    +ostree_repo_remote_list_refs (OstreeRepo *self,
    +                              const char *remote_name,
    +                              GHashTable **out_all_refs,
    +                              GCancellable *cancellable,
    +                              GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of the remote.

     

    out_all_refs

    Mapping from ref to checksum.

    [out][element-type utf8 utf8][transfer container]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_resolve_collection_ref ()

    +
    gboolean
    +ostree_repo_resolve_collection_ref (OstreeRepo *self,
    +                                    const OstreeCollectionRef *ref,
    +                                    gboolean allow_noent,
    +                                    OstreeRepoResolveRevExtFlags flags,
    +                                    char **out_rev,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Look up the checksum for the given collection–ref, returning it in out_rev +. +This will search through the mirrors and remote refs.

    +

    If allow_noent + is TRUE and the given ref + cannot be found, TRUE will be +returned and out_rev + will be set to NULL. If allow_noent + is FALSE and +the given ref + cannot be found, a G_IO_ERROR_NOT_FOUND error will be +returned.

    +

    If you want to check only local refs, not remote or mirrored ones, use the +flag OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY. This is analogous to using +ostree_repo_resolve_rev_ext() but for collection-refs.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    ref

    a collection–ref to resolve

     

    allow_noent

    TRUE to not throw an error if ref +doesn’t exist

     

    flags

    options controlling behaviour

     

    out_rev

    return location for +the checksum corresponding to ref +, or NULL if allow_noent +is TRUE and +the ref +could not be found.

    [out][transfer full][optional][nullable]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_load_variant ()

    +
    gboolean
    +ostree_repo_load_variant (OstreeRepo *self,
    +                          OstreeObjectType objtype,
    +                          const char *sha256,
    +                          GVariant **out_variant,
    +                          GError **error);
    +

    Load the metadata object sha256 + of type objtype +, storing the +result in out_variant +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Expected object type

     

    sha256

    Checksum string

     

    out_variant

    Metadata object.

    [out][transfer full]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_load_commit ()

    +
    gboolean
    +ostree_repo_load_commit (OstreeRepo *self,
    +                         const char *checksum,
    +                         GVariant **out_commit,
    +                         OstreeRepoCommitState *out_state,
    +                         GError **error);
    +

    A version of ostree_repo_load_variant() specialized to commits, +capable of returning extended state information. Currently +the only extended state is OSTREE_REPO_COMMIT_STATE_PARTIAL, which +means that only a sub-path of the commit is available.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    Commit checksum

     

    out_commit

    Commit.

    [out][allow-none]

    out_state

    Commit state.

    [out][allow-none]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_load_variant_if_exists ()

    +
    gboolean
    +ostree_repo_load_variant_if_exists (OstreeRepo *self,
    +                                    OstreeObjectType objtype,
    +                                    const char *sha256,
    +                                    GVariant **out_variant,
    +                                    GError **error);
    +

    Attempt to load the metadata object sha256 + of type objtype + if it +exists, storing the result in out_variant +. If it doesn't exist, +out_variant + will be set to NULL and the function will still +return TRUE.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    sha256

    ASCII checksum

     

    out_variant

    Metadata.

    [out][nullable][transfer full]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_load_file ()

    +
    gboolean
    +ostree_repo_load_file (OstreeRepo *self,
    +                       const char *checksum,
    +                       GInputStream **out_input,
    +                       GFileInfo **out_file_info,
    +                       GVariant **out_xattrs,
    +                       GCancellable *cancellable,
    +                       GError **error);
    +

    Load content object, decomposing it into three parts: the actual +content (for regular files), the metadata, and extended attributes.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    ASCII SHA256 checksum

     

    out_input

    File content.

    [out][optional][nullable]

    out_file_info

    File information.

    [out][optional][nullable]

    out_xattrs

    Extended attributes.

    [out][optional][nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_load_object_stream ()

    +
    gboolean
    +ostree_repo_load_object_stream (OstreeRepo *self,
    +                                OstreeObjectType objtype,
    +                                const char *checksum,
    +                                GInputStream **out_input,
    +                                guint64 *out_size,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Load object as a stream; useful when copying objects between +repositories.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    checksum

    ASCII SHA256 checksum

     

    out_input

    Stream for object.

    [out]

    out_size

    Length of out_input +.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_query_object_storage_size ()

    +
    gboolean
    +ostree_repo_query_object_storage_size (OstreeRepo *self,
    +                                       OstreeObjectType objtype,
    +                                       const char *sha256,
    +                                       guint64 *out_size,
    +                                       GCancellable *cancellable,
    +                                       GError **error);
    +

    Return the size in bytes of object with checksum sha256 +, after any +compression has been applied.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    sha256

    Checksum

     

    out_size

    Size in bytes object occupies physically.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_import_object_from ()

    +
    gboolean
    +ostree_repo_import_object_from (OstreeRepo *self,
    +                                OstreeRepo *source,
    +                                OstreeObjectType objtype,
    +                                const char *checksum,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Copy object named by objtype + and checksum + into self + from the +source repository source +. If both repositories are of the same +type and on the same filesystem, this will simply be a fast Unix +hard link operation.

    +

    Otherwise, a copy will be performed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Destination repo

     

    source

    Source repo

     

    objtype

    Object type

     

    checksum

    checksum

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_import_object_from_with_trust ()

    +
    gboolean
    +ostree_repo_import_object_from_with_trust
    +                               (OstreeRepo *self,
    +                                OstreeRepo *source,
    +                                OstreeObjectType objtype,
    +                                const char *checksum,
    +                                gboolean trusted,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Copy object named by objtype + and checksum + into self + from the +source repository source +. If trusted + is TRUE and both +repositories are of the same type and on the same filesystem, +this will simply be a fast Unix hard link operation.

    +

    Otherwise, a copy will be performed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Destination repo

     

    source

    Source repo

     

    objtype

    Object type

     

    checksum

    checksum

     

    trusted

    If TRUE, assume the source repo is valid and trusted

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_repo_import_archive_to_mtree ()

    +
    gboolean
    +ostree_repo_import_archive_to_mtree (OstreeRepo *self,
    +                                     OstreeRepoImportArchiveOptions *opts,
    +                                     void *archive,
    +                                     OstreeMutableTree *mtree,
    +                                     OstreeRepoCommitModifier *modifier,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Import an archive file archive + into the repository, and write its +file structure to mtree +.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    opts

    Options structure, ensure this is zeroed, then set specific variables

     

    archive

    Really this is "struct archive*"

     

    mtree

    The OstreeMutableTree to write to

     

    modifier

    Optional commit modifier.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_export_tree_to_archive ()

    +
    gboolean
    +ostree_repo_export_tree_to_archive (OstreeRepo *self,
    +                                    OstreeRepoExportArchiveOptions *opts,
    +                                    OstreeRepoFile *root,
    +                                    void *archive,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Import an archive file archive + into the repository, and write its +file structure to mtree +.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    opts

    Options controlling conversion

     

    root

    An OstreeRepoFile for the base directory

     

    archive

    A struct archive, but specified as void to avoid a dependency on the libarchive +headers

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_delete_object ()

    +
    gboolean
    +ostree_repo_delete_object (OstreeRepo *self,
    +                           OstreeObjectType objtype,
    +                           const char *sha256,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Remove the object of type objtype + with checksum sha256 + +from the repository. An error of type G_IO_ERROR_NOT_FOUND +is thrown if the object does not exist.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    sha256

    Checksum

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_fsck_object ()

    +
    gboolean
    +ostree_repo_fsck_object (OstreeRepo *self,
    +                         OstreeObjectType objtype,
    +                         const char *sha256,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Verify consistency of the object; this performs checks only relevant to the +immediate object itself, such as checksumming. This API call will not itself +traverse metadata objects for example.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    objtype

    Object type

     

    sha256

    Checksum

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2017.15

    +
    +
    +
    +

    OstreeRepoCommitFilter ()

    +
    OstreeRepoCommitFilterResult
    +(*OstreeRepoCommitFilter) (OstreeRepo *repo,
    +                           const char *path,
    +                           GFileInfo *file_info,
    +                           gpointer user_data);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    path

    Path to file

     

    file_info

    File information

     

    user_data

    User data

     
    +
    +
    +

    Returns

    +

    OstreeRepoCommitFilterResult saying whether or not to commit this file

    +
    +
    +
    +
    +

    ostree_repo_commit_modifier_new ()

    +
    OstreeRepoCommitModifier *
    +ostree_repo_commit_modifier_new (OstreeRepoCommitModifierFlags flags,
    +                                 OstreeRepoCommitFilter commit_filter,
    +                                 gpointer user_data,
    +                                 GDestroyNotify destroy_notify);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    flags

    Control options for filter

     

    commit_filter

    Function that can inspect individual files.

    [allow-none]

    user_data

    User data.

    [allow-none]

    destroy_notify

    A GDestroyNotify

     
    +
    +
    +

    Returns

    +

    A new commit modifier.

    +

    [transfer full]

    +
    +
    +
    +
    +

    OstreeRepoCommitModifierXattrCallback ()

    +
    GVariant *
    +(*OstreeRepoCommitModifierXattrCallback)
    +                               (OstreeRepo *repo,
    +                                const char *path,
    +                                GFileInfo *file_info,
    +                                gpointer user_data);
    +
    +
    +
    +

    ostree_repo_commit_modifier_set_xattr_callback ()

    +
    void
    +ostree_repo_commit_modifier_set_xattr_callback
    +                               (OstreeRepoCommitModifier *modifier,
    +                                OstreeRepoCommitModifierXattrCallback callback,
    +                                GDestroyNotify destroy,
    +                                gpointer user_data);
    +

    If set, this function should return extended attributes to use for +the given path. This is useful for things like ACLs and SELinux, +where a build system can label the files as it's committing to the +repository.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    modifier

    An OstreeRepoCommitModifier

     

    callback

    Function to be invoked, should return extended attributes for path

     

    destroy

    Destroy notification

     

    user_data

    Data for callback +:

     
    +
    +
    +
    +
    +

    ostree_repo_commit_modifier_set_sepolicy ()

    +
    void
    +ostree_repo_commit_modifier_set_sepolicy
    +                               (OstreeRepoCommitModifier *modifier,
    +                                OstreeSePolicy *sepolicy);
    +

    If policy + is non-NULL, use it to look up labels to use for +"security.selinux" extended attributes.

    +

    Note that any policy specified this way operates in addition to any +extended attributes provided via +ostree_repo_commit_modifier_set_xattr_callback(). However if both +specify a value for "security.selinux", then the one from the +policy wins.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    modifier

    An OstreeRepoCommitModifier

     

    sepolicy

    Policy to use for labeling.

    [allow-none]
    +
    +
    +
    +
    +

    ostree_repo_commit_modifier_set_sepolicy_from_commit ()

    +
    gboolean
    +ostree_repo_commit_modifier_set_sepolicy_from_commit
    +                               (OstreeRepoCommitModifier *modifier,
    +                                OstreeRepo *repo,
    +                                const char *rev,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    In many cases, one wants to create a "derived" commit from base commit. +SELinux policy labels are part of that base commit. This API allows +one to easily set up SELinux labeling from a base commit.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    modifier

    Commit modifier

     

    repo

    OSTree repo containing rev +

     

    rev

    Find SELinux policy from this base commit

     
    +
    +

    Since: 2020.4

    +
    +
    +
    +

    ostree_repo_commit_modifier_set_devino_cache ()

    +
    void
    +ostree_repo_commit_modifier_set_devino_cache
    +                               (OstreeRepoCommitModifier *modifier,
    +                                OstreeRepoDevInoCache *cache);
    +

    See the documentation for +ostree_repo_devino_cache_new(). This function can +then be used for later calls to +ostree_repo_write_directory_to_mtree() to optimize commits.

    +

    Note if your process has multiple writers, you should use separate +OSTreeRepo instances if you want to also use this API.

    +

    This function will add a reference to cache + without copying - you +should avoid further mutation of the cache.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    modifier

    Modifier

     

    cache

    A hash table caching device,inode to checksums

     
    +
    +

    Since: 2017.13

    +
    +
    +
    +

    ostree_repo_commit_modifier_ref ()

    +
    OstreeRepoCommitModifier *
    +ostree_repo_commit_modifier_ref (OstreeRepoCommitModifier *modifier);
    +
    +
    +
    +

    ostree_repo_commit_modifier_unref ()

    +
    void
    +ostree_repo_commit_modifier_unref (OstreeRepoCommitModifier *modifier);
    +
    +
    +
    +

    ostree_repo_devino_cache_new ()

    +
    OstreeRepoDevInoCache *
    +ostree_repo_devino_cache_new (void);
    +

    OSTree has support for pairing ostree_repo_checkout_tree_at() using +hardlinks in combination with a later +ostree_repo_write_directory_to_mtree() using a (normally modified) +directory. In order for OSTree to optimally detect just the new +files, use this function and fill in the devino_to_csum_cache +member of OstreeRepoCheckoutAtOptions, then call +ostree_repo_commit_set_devino_cache().

    +
    +

    Returns

    +

    Newly allocated cache.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_devino_cache_ref ()

    +
    OstreeRepoDevInoCache *
    +ostree_repo_devino_cache_ref (OstreeRepoDevInoCache *cache);
    +
    +
    +
    +

    ostree_repo_devino_cache_unref ()

    +
    void
    +ostree_repo_devino_cache_unref (OstreeRepoDevInoCache *cache);
    +
    +
    +
    +

    ostree_repo_devino_cache_get_type ()

    +
    GType
    +ostree_repo_devino_cache_get_type (void);
    +
    +
    +
    +

    ostree_repo_write_directory_to_mtree ()

    +
    gboolean
    +ostree_repo_write_directory_to_mtree (OstreeRepo *self,
    +                                      GFile *dir,
    +                                      OstreeMutableTree *mtree,
    +                                      OstreeRepoCommitModifier *modifier,
    +                                      GCancellable *cancellable,
    +                                      GError **error);
    +

    Store objects for dir + and all children into the repository self +, +overlaying the resulting filesystem hierarchy into mtree +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    dir

    Path to a directory

     

    mtree

    Overlay directory contents into this tree

     

    modifier

    Optional modifier.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_dfd_to_mtree ()

    +
    gboolean
    +ostree_repo_write_dfd_to_mtree (OstreeRepo *self,
    +                                int dfd,
    +                                const char *path,
    +                                OstreeMutableTree *mtree,
    +                                OstreeRepoCommitModifier *modifier,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Store as objects all contents of the directory referred to by dfd + +and path + all children into the repository self +, overlaying the +resulting filesystem hierarchy into mtree +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    dfd

    Directory file descriptor

     

    path

    Path

     

    mtree

    Overlay directory contents into this tree

     

    modifier

    Optional modifier.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_archive_to_mtree ()

    +
    gboolean
    +ostree_repo_write_archive_to_mtree (OstreeRepo *self,
    +                                    GFile *archive,
    +                                    OstreeMutableTree *mtree,
    +                                    OstreeRepoCommitModifier *modifier,
    +                                    gboolean autocreate_parents,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Import an archive file archive + into the repository, and write its +file structure to mtree +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    archive

    A path to an archive file

     

    mtree

    The OstreeMutableTree to write to

     

    modifier

    Optional commit modifier.

    [allow-none]

    autocreate_parents

    Autocreate parent directories

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_archive_to_mtree_from_fd ()

    +
    gboolean
    +ostree_repo_write_archive_to_mtree_from_fd
    +                               (OstreeRepo *self,
    +                                int fd,
    +                                OstreeMutableTree *mtree,
    +                                OstreeRepoCommitModifier *modifier,
    +                                gboolean autocreate_parents,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Read an archive from fd + and import it into the repository, writing +its file structure to mtree +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    An OstreeRepo

     

    fd

    A file descriptor to read the archive from

     

    mtree

    The OstreeMutableTree to write to

     

    modifier

    Optional commit modifier.

    [allow-none]

    autocreate_parents

    Autocreate parent directories

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_mtree ()

    +
    gboolean
    +ostree_repo_write_mtree (OstreeRepo *self,
    +                         OstreeMutableTree *mtree,
    +                         GFile **out_file,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Write all metadata objects for mtree + to repo; the resulting +out_file + points to the OSTREE_OBJECT_TYPE_DIR_TREE object that +the mtree + represented.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    mtree

    Mutable tree

     

    out_file

    An OstreeRepoFile representing mtree +'s root.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_commit ()

    +
    gboolean
    +ostree_repo_write_commit (OstreeRepo *self,
    +                          const char *parent,
    +                          const char *subject,
    +                          const char *body,
    +                          GVariant *metadata,
    +                          OstreeRepoFile *root,
    +                          char **out_commit,
    +                          GCancellable *cancellable,
    +                          GError **error);
    +

    Write a commit metadata object, referencing root_contents_checksum + +and root_metadata_checksum +. +This uses the current time as the commit timestamp, but it can be +overridden with an explicit timestamp via the +standard +SOURCE_DATE_EPOCH environment flag.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    parent

    ASCII SHA256 checksum for parent, or NULL for none.

    [nullable]

    subject

    Subject.

    [nullable]

    body

    Body.

    [nullable]

    metadata

    GVariant of type a{sv}, or NULL for none.

    [nullable]

    root

    The tree to point the commit to

     

    out_commit

    Resulting ASCII SHA256 checksum for +commit.

    [out][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_commit_with_time ()

    +
    gboolean
    +ostree_repo_write_commit_with_time (OstreeRepo *self,
    +                                    const char *parent,
    +                                    const char *subject,
    +                                    const char *body,
    +                                    GVariant *metadata,
    +                                    OstreeRepoFile *root,
    +                                    guint64 time,
    +                                    char **out_commit,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Write a commit metadata object, referencing root_contents_checksum + +and root_metadata_checksum +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    parent

    ASCII SHA256 checksum for parent, or NULL for none.

    [nullable]

    subject

    Subject.

    [nullable]

    body

    Body.

    [nullable]

    metadata

    GVariant of type a{sv}, or NULL for none.

    [nullable]

    root

    The tree to point the commit to

     

    time

    The time to use to stamp the commit

     

    out_commit

    Resulting ASCII SHA256 checksum for +commit.

    [out][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_read_commit_detached_metadata ()

    +
    gboolean
    +ostree_repo_read_commit_detached_metadata
    +                               (OstreeRepo *self,
    +                                const char *checksum,
    +                                GVariant **out_metadata,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    OSTree commits can have arbitrary metadata associated; this +function retrieves them. If none exists, out_metadata + will be set +to NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    ASCII SHA256 commit checksum

     

    out_metadata

    Metadata associated with commit in with format +"a{sv}", or NULL if none exists.

    [out][nullable][transfer full]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_write_commit_detached_metadata ()

    +
    gboolean
    +ostree_repo_write_commit_detached_metadata
    +                               (OstreeRepo *self,
    +                                const char *checksum,
    +                                GVariant *metadata,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Replace any existing metadata associated with commit referred to by +checksum + with metadata +. If metadata + is NULL, then existing +data will be deleted.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    checksum

    ASCII SHA256 commit checksum

     

    metadata

    Metadata to associate with commit in with format "a{sv}", or NULL to +delete.

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_commit_add_composefs_metadata ()

    +
    gboolean
    +ostree_repo_commit_add_composefs_metadata
    +                               (OstreeRepo *self,
    +                                guint format_version,
    +                                GVariantDict *dict,
    +                                OstreeRepoFile *repo_root,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Compute the composefs digest for a filesystem tree +and insert it into metadata for a commit object. The composefs +digest covers the entire filesystem tree and can be verified by +the composefs mount tooling.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    format_version

    Must be zero

     

    dict

    A GVariant builder of type a{sv}

     

    repo_root

    the target filesystem tree

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_checkout_at_options_set_devino ()

    +
    void
    +ostree_repo_checkout_at_options_set_devino
    +                               (OstreeRepoCheckoutAtOptions *opts,
    +                                OstreeRepoDevInoCache *cache);
    +

    This function simply assigns cache + to the devino_to_csum_cache member of +opts +; it's only useful for introspection.

    +

    Note that cache does *not* have its refcount incremented - the lifetime of +cache + must be equal to or greater than that of opts +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    opts

    Checkout options

     

    cache

    Devino cache.

    [transfer none][nullable]
    +
    +

    Since: 2017.13

    +
    +
    +
    +

    ostree_repo_checkout_tree ()

    +
    gboolean
    +ostree_repo_checkout_tree (OstreeRepo *self,
    +                           OstreeRepoCheckoutMode mode,
    +                           OstreeRepoCheckoutOverwriteMode overwrite_mode,
    +                           GFile *destination,
    +                           OstreeRepoFile *source,
    +                           GFileInfo *source_info,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Check out source + into destination +, which must live on the +physical filesystem. source + may be any subdirectory of a given +commit. The mode + and overwrite_mode + allow control over how the +files are checked out.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    mode

    Options controlling all files

     

    overwrite_mode

    Whether or not to overwrite files

     

    destination

    Place tree here

     

    source

    Source tree

     

    source_info

    Source info

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_checkout_tree_at ()

    +
    gboolean
    +ostree_repo_checkout_tree_at (OstreeRepo *self,
    +                              OstreeRepoCheckoutOptions *options,
    +                              int destination_dfd,
    +                              const char *destination_path,
    +                              const char *commit,
    +                              GCancellable *cancellable,
    +                              GError **error);
    +

    ostree_repo_checkout_tree_at is deprecated and should not be used in newly-written code.

    +

    Similar to ostree_repo_checkout_tree(), but uses directory-relative +paths for the destination, uses a new OstreeRepoCheckoutAtOptions, +and takes a commit checksum and optional subpath pair, rather than +requiring use of GFile APIs for the caller.

    +

    Note in addition that unlike ostree_repo_checkout_tree(), the +default is not to use the repository-internal uncompressed objects +cache.

    +

    This function is deprecated. Use ostree_repo_checkout_at() instead.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    options

    Options.

    [allow-none]

    destination_dfd

    Directory FD for destination

     

    destination_path

    Directory for destination

     

    commit

    Checksum for commit

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_checkout_at ()

    +
    gboolean
    +ostree_repo_checkout_at (OstreeRepo *self,
    +                         OstreeRepoCheckoutAtOptions *options,
    +                         int destination_dfd,
    +                         const char *destination_path,
    +                         const char *commit,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Similar to ostree_repo_checkout_tree(), but uses directory-relative +paths for the destination, uses a new OstreeRepoCheckoutAtOptions, +and takes a commit checksum and optional subpath pair, rather than +requiring use of GFile APIs for the caller.

    +

    It also replaces ostree_repo_checkout_at() which was not safe to +use with GObject introspection.

    +

    Note in addition that unlike ostree_repo_checkout_tree(), the +default is not to use the repository-internal uncompressed objects +cache.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    options

    Options.

    [allow-none]

    destination_dfd

    Directory FD for destination

     

    destination_path

    Directory for destination

     

    commit

    Checksum for commit

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.8

    +
    +
    +
    +

    ostree_repo_checkout_gc ()

    +
    gboolean
    +ostree_repo_checkout_gc (OstreeRepo *self,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Call this after finishing a succession of checkout operations; it +will delete any currently-unused uncompressed objects from the +cache.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_read_commit ()

    +
    gboolean
    +ostree_repo_read_commit (OstreeRepo *self,
    +                         const char *ref,
    +                         GFile **out_root,
    +                         char **out_commit,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Load the content for rev + into out_root +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    ref

    Ref or ASCII checksum

     

    out_root

    An OstreeRepoFile corresponding to the root.

    [out][optional]

    out_commit

    The resolved commit checksum.

    [out][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_list_objects ()

    +
    gboolean
    +ostree_repo_list_objects (OstreeRepo *self,
    +                          OstreeRepoListObjectsFlags flags,
    +                          GHashTable **out_objects,
    +                          GCancellable *cancellable,
    +                          GError **error);
    +

    This function synchronously enumerates all objects in the +repository, returning data in out_objects +. out_objects + +maps from keys returned by ostree_object_name_serialize() +to GVariant values of type OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    flags

    Flags controlling enumeration

     

    out_objects

    Map of serialized object name to variant data.

    [out][transfer container][element-type GVariant GVariant]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on error, and error +will be set

    +
    +
    +
    +
    +

    ostree_repo_list_commit_objects_starting_with ()

    +
    gboolean
    +ostree_repo_list_commit_objects_starting_with
    +                               (OstreeRepo *self,
    +                                const char *start,
    +                                GHashTable **out_commits,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    This function synchronously enumerates all commit objects starting +with start +, returning data in out_commits +.

    +

    To list all commit objects, provide the empty string "" for start +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    start

    List commits starting with this checksum (empty string for all)

     

    out_commits

    Map of serialized commit name to variant data.

    [out][transfer container][element-type GVariant GVariant]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on error, and error +will be set

    +
    +
    +
    +
    +

    ostree_repo_list_static_delta_names ()

    +
    gboolean
    +ostree_repo_list_static_delta_names (OstreeRepo *self,
    +                                     GPtrArray **out_deltas,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    This function synchronously enumerates all static deltas in the +repository, returning its result in out_deltas +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    out_deltas

    String name of deltas +(checksum-checksum.delta).

    [out][element-type utf8][transfer container]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_list_static_delta_indexes ()

    +
    gboolean
    +ostree_repo_list_static_delta_indexes (OstreeRepo *self,
    +                                       GPtrArray **out_indexes,
    +                                       GCancellable *cancellable,
    +                                       GError **error);
    +

    This function synchronously enumerates all static delta indexes in the +repository, returning its result in out_indexes +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    out_indexes

    String name of delta indexes +(checksum).

    [out][element-type utf8][transfer container]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.8

    +
    +
    +
    +

    ostree_repo_static_delta_reindex ()

    +
    gboolean
    +ostree_repo_static_delta_reindex (OstreeRepo *repo,
    +                                  OstreeStaticDeltaIndexFlags flags,
    +                                  const char *opt_to_commit,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    The delta index for a particular commit lists all the existing deltas that can be used +when downloading that commit. This operation regenerates these indexes, either for +a particular commit (if opt_to_commit + is non-NULL), or for all commits that +are reachable by an existing delta (if opt_to_commit + is NULL).

    +

    This is normally called automatically when the summary is updated in +ostree_repo_regenerate_summary().

    +

    Locking: shared

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    flags

    Flags affecting the indexing operation

     

    opt_to_commit

    ASCII SHA256 checksum of target commit, or NULL to index all targets

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.8

    +
    +
    +
    +

    ostree_repo_static_delta_generate ()

    +
    gboolean
    +ostree_repo_static_delta_generate (OstreeRepo *self,
    +                                   OstreeStaticDeltaGenerateOpt opt,
    +                                   const char *from,
    +                                   const char *to,
    +                                   GVariant *metadata,
    +                                   GVariant *params,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Generate a lookaside "static delta" from from + (NULL means +from-empty) which can generate the objects in to +. This delta is +an optimization over fetching individual objects, and can be +conveniently stored and applied offline.

    +

    The params + argument should be an a{sv}. The following attributes +are known:

    +
      +
    • min-fallback-size: u: Minimum uncompressed size in megabytes to use fallback, 0 to disable +fallbacks

    • +
    • max-chunk-size: u: Maximum size in megabytes of a delta part

    • +
    • max-bsdiff-size: u: Maximum size in megabytes to consider bsdiff compression +for input files

    • +
    • compression: y: Compression type: 0=none, x=lzma, g=gzip

    • +
    • bsdiff-enabled: b: Enable bsdiff compression. Default TRUE.

    • +
    • inline-parts: b: Put part data in header, to get a single file delta. Default FALSE.

    • +
    • verbose: b: Print diagnostic messages. Default FALSE.

    • +
    • endianness: b: Deltas use host byte order by default; this option allows choosing +(G_BIG_ENDIAN or G_LITTLE_ENDIAN)

    • +
    • filename: ^ay: Save delta superblock to this filename (bytestring), and parts in the same +directory. Default saves to repository.

    • +
    • sign-name: ^ay: Signature type to use (bytestring).

    • +
    • sign-key-ids: ^as: NULL-terminated array of keys used to sign delta superblock.

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    opt

    High level optimization choice

     

    from

    ASCII SHA256 checksum of origin, or NULL.

    [nullable]

    to

    ASCII SHA256 checksum of target

     

    metadata

    Optional metadata.

    [nullable]

    params

    Parameters, see below.

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_static_delta_execute_offline_with_signature ()

    +
    gboolean
    +ostree_repo_static_delta_execute_offline_with_signature
    +                               (OstreeRepo *self,
    +                                GFile *dir_or_file,
    +                                OstreeSign *sign,
    +                                gboolean skip_validation,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Given a directory representing an already-downloaded static delta +on disk, apply it, generating a new commit. +If sign is passed, the static delta signature is verified. +If sign-verify-deltas configuration option is set and static delta is signed, +signature verification will be mandatory before apply the static delta. +The directory must be named with the form "FROM-TO", where both are +checksums, and it must contain a file named "superblock", along with at least +one part.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    dir_or_file

    Path to a directory containing static delta data, or directly to the superblock

     

    sign

    Signature engine used to check superblock

     

    skip_validation

    If TRUE, assume data integrity

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_repo_static_delta_execute_offline ()

    +
    gboolean
    +ostree_repo_static_delta_execute_offline
    +                               (OstreeRepo *self,
    +                                GFile *dir_or_file,
    +                                gboolean skip_validation,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Given a directory representing an already-downloaded static delta +on disk, apply it, generating a new commit. The directory must be +named with the form "FROM-TO", where both are checksums, and it +must contain a file named "superblock", along with at least one part.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    dir_or_file

    Path to a directory containing static delta data, or directly to the superblock

     

    skip_validation

    If TRUE, assume data integrity

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_static_delta_verify_signature ()

    +
    gboolean
    +ostree_repo_static_delta_verify_signature
    +                               (OstreeRepo *self,
    +                                const char *delta_id,
    +                                OstreeSign *sign,
    +                                char **out_success_message,
    +                                GError **error);
    +

    Verify static delta file signature.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    delta_id

    delta path

     

    sign

    Signature engine used to check superblock

     

    out_success_message

    success message.

    [out][nullable][optional]

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if the signature of static delta file is valid using the +signature engine provided, FALSE otherwise.

    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_repo_traverse_new_reachable ()

    +
    GHashTable *
    +ostree_repo_traverse_new_reachable (void);
    +

    This hash table is a set of GVariant which can be accessed via +ostree_object_name_deserialize().

    +
    +

    Returns

    +

    A new hash table.

    +

    [transfer container][element-type GVariant GVariant]

    +
    +
    +
    +
    +

    ostree_repo_traverse_new_parents ()

    +
    GHashTable *
    +ostree_repo_traverse_new_parents (void);
    +

    This hash table is a mapping from GVariant which can be accessed +via ostree_object_name_deserialize() to a GVariant containing either +a similar GVariant or and array of them, listing the parents of the key.

    +
    +

    Returns

    +

    A new hash table.

    +

    [transfer container][element-type GVariant GVariant]

    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_repo_traverse_parents_get_commits ()

    +
    char **
    +ostree_repo_traverse_parents_get_commits
    +                               (GHashTable *parents,
    +                                GVariant *object);
    +

    Gets all the commits that a certain object belongs to, as recorded +by a parents table gotten from ostree_repo_traverse_commit_union_with_parents.

    +
    +

    Returns

    +

    An array of checksums for +the commits the key belongs to.

    +

    [transfer full][array zero-terminated=1]

    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_repo_traverse_commit ()

    +
    gboolean
    +ostree_repo_traverse_commit (OstreeRepo *repo,
    +                             const char *commit_checksum,
    +                             int maxdepth,
    +                             GHashTable **out_reachable,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +

    Create a new set out_reachable + containing all objects reachable +from commit_checksum +, traversing maxdepth + parent commits.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    commit_checksum

    ASCII SHA256 checksum

     

    maxdepth

    Traverse this many parent commits, -1 for unlimited

     

    out_reachable

    Set of reachable +objects.

    [out][transfer container][element-type GVariant GVariant]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_traverse_commit_union ()

    +
    gboolean
    +ostree_repo_traverse_commit_union (OstreeRepo *repo,
    +                                   const char *commit_checksum,
    +                                   int maxdepth,
    +                                   GHashTable *inout_reachable,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Update the set inout_reachable + containing all objects reachable +from commit_checksum +, traversing maxdepth + parent commits.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    commit_checksum

    ASCII SHA256 checksum

     

    maxdepth

    Traverse this many parent commits, -1 for unlimited

     

    inout_reachable

    Set of reachable objects

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_traverse_commit_union_with_parents ()

    +
    gboolean
    +ostree_repo_traverse_commit_union_with_parents
    +                               (OstreeRepo *repo,
    +                                const char *commit_checksum,
    +                                int maxdepth,
    +                                GHashTable *inout_reachable,
    +                                GHashTable *inout_parents,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Update the set inout_reachable + containing all objects reachable +from commit_checksum +, traversing maxdepth + parent commits.

    +

    Additionally this constructs a mapping from each object to the parents +of the object, which can be used to track which commits an object +belongs to.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    commit_checksum

    ASCII SHA256 checksum

     

    maxdepth

    Traverse this many parent commits, -1 for unlimited

     

    inout_reachable

    Set of reachable objects

     

    inout_parents

    Map from object to parent object

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_repo_traverse_commit_with_flags ()

    +
    gboolean
    +ostree_repo_traverse_commit_with_flags
    +                               (OstreeRepo *repo,
    +                                OstreeRepoCommitTraverseFlags flags,
    +                                const char *commit_checksum,
    +                                int maxdepth,
    +                                GHashTable *inout_reachable,
    +                                GHashTable *inout_parents,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Update the set inout_reachable + containing all objects reachable +from commit_checksum +, traversing maxdepth + parent commits.

    +

    Additionally this constructs a mapping from each object to the parents +of the object, which can be used to track which commits an object +belongs to.

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    flags

    change traversal behaviour according to these flags

     

    commit_checksum

    ASCII SHA256 checksum

     

    maxdepth

    Traverse this many parent commits, -1 for unlimited

     

    inout_reachable

    Set of reachable objects

     

    inout_parents

    Map from object to parent object

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_cleanup ()

    +
    void
    +ostree_repo_commit_traverse_iter_cleanup
    +                               (void *p);
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_clear ()

    +
    void
    +ostree_repo_commit_traverse_iter_clear
    +                               (OstreeRepoCommitTraverseIter *iter);
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_get_dir ()

    +
    void
    +ostree_repo_commit_traverse_iter_get_dir
    +                               (OstreeRepoCommitTraverseIter *iter,
    +                                char **out_name,
    +                                char **out_content_checksum,
    +                                char **out_meta_checksum);
    +

    Return information on the current directory. This function may +only be called if OSTREE_REPO_COMMIT_ITER_RESULT_DIR was returned +from ostree_repo_commit_traverse_iter_next().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    iter

    An iter

     

    out_name

    Name of current dir.

    [out][transfer none]

    out_content_checksum

    Checksum of current content.

    [out][transfer none]

    out_meta_checksum

    Checksum of current metadata.

    [out][transfer none]
    +
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_get_file ()

    +
    void
    +ostree_repo_commit_traverse_iter_get_file
    +                               (OstreeRepoCommitTraverseIter *iter,
    +                                char **out_name,
    +                                char **out_checksum);
    +

    Return information on the current file. This function may only be +called if OSTREE_REPO_COMMIT_ITER_RESULT_FILE was returned from +ostree_repo_commit_traverse_iter_next().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    iter

    An iter

     

    out_name

    Name of current file.

    [out][transfer none]

    out_checksum

    Checksum of current file.

    [out][transfer none]
    +
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_init_commit ()

    +
    gboolean
    +ostree_repo_commit_traverse_iter_init_commit
    +                               (OstreeRepoCommitTraverseIter *iter,
    +                                OstreeRepo *repo,
    +                                GVariant *commit,
    +                                OstreeRepoCommitTraverseFlags flags,
    +                                GError **error);
    +

    Initialize (in place) an iterator over the root of a commit object.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    iter

    An iter

     

    repo

    A repo

     

    commit

    Variant of type OSTREE_OBJECT_TYPE_COMMIT

     

    flags

    Flags

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_init_dirtree ()

    +
    gboolean
    +ostree_repo_commit_traverse_iter_init_dirtree
    +                               (OstreeRepoCommitTraverseIter *iter,
    +                                OstreeRepo *repo,
    +                                GVariant *dirtree,
    +                                OstreeRepoCommitTraverseFlags flags,
    +                                GError **error);
    +

    Initialize (in place) an iterator over a directory tree.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    iter

    An iter

     

    repo

    A repo

     

    dirtree

    Variant of type OSTREE_OBJECT_TYPE_DIR_TREE

     

    flags

    Flags

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_commit_traverse_iter_next ()

    +
    OstreeRepoCommitIterResult
    +ostree_repo_commit_traverse_iter_next (OstreeRepoCommitTraverseIter *iter,
    +                                       GCancellable *cancellable,
    +                                       GError **error);
    +

    Step the interator to the next item. Files will be returned first, +then subdirectories. Call this in a loop; upon encountering +OSTREE_REPO_COMMIT_ITER_RESULT_END, there will be no more files or +directories. If OSTREE_REPO_COMMIT_ITER_RESULT_DIR is returned, +then call ostree_repo_commit_traverse_iter_get_dir() to retrieve +data for that directory. Similarly, if +OSTREE_REPO_COMMIT_ITER_RESULT_FILE is returned, call +ostree_repo_commit_traverse_iter_get_file().

    +

    If OSTREE_REPO_COMMIT_ITER_RESULT_ERROR is returned, it is a +program error to call any further API on iter + except for +ostree_repo_commit_traverse_iter_clear().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    iter

    An iter

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_prune ()

    +
    gboolean
    +ostree_repo_prune (OstreeRepo *self,
    +                   OstreeRepoPruneFlags flags,
    +                   gint depth,
    +                   gint *out_objects_total,
    +                   gint *out_objects_pruned,
    +                   guint64 *out_pruned_object_size_total,
    +                   GCancellable *cancellable,
    +                   GError **error);
    +

    Delete content from the repository. By default, this function will +only delete "orphaned" objects not referred to by any commit. This +can happen during a local commit operation, when we have written +content objects but not saved the commit referencing them.

    +

    However, if OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY is provided, instead +of traversing all commits, only refs will be used. Particularly +when combined with depth +, this is a convenient way to delete +history from the repository.

    +

    Use the OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE to just determine +statistics on objects that would be deleted, without actually +deleting them.

    +

    Locking: exclusive

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    flags

    Options controlling prune process

     

    depth

    Stop traversal after this many iterations (-1 for unlimited)

     

    out_objects_total

    Number of objects found.

    [out]

    out_objects_pruned

    Number of objects deleted.

    [out]

    out_pruned_object_size_total

    Storage size in bytes of objects deleted.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_prune_static_deltas ()

    +
    gboolean
    +ostree_repo_prune_static_deltas (OstreeRepo *self,
    +                                 const char *commit,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Prune static deltas, if COMMIT is specified then delete static delta files only +targeting that commit; otherwise any static delta of non existing commits are +deleted.

    +

    Locking: exclusive

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    commit

    ASCII SHA256 checksum for commit, or NULL for each +non existing commit.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_traverse_reachable_refs ()

    +
    gboolean
    +ostree_repo_traverse_reachable_refs (OstreeRepo *self,
    +                                     guint depth,
    +                                     GHashTable *reachable,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Add all commit objects directly reachable via a ref to reachable +.

    +

    Locking: shared

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    depth

    Depth of traversal

     

    reachable

    Set of reachable objects (will be modified).

    [element-type GVariant GVariant]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_prune_from_reachable ()

    +
    gboolean
    +ostree_repo_prune_from_reachable (OstreeRepo *self,
    +                                  OstreeRepoPruneOptions *options,
    +                                  gint *out_objects_total,
    +                                  gint *out_objects_pruned,
    +                                  guint64 *out_pruned_object_size_total,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Delete content from the repository. This function is the "backend" +half of the higher level ostree_repo_prune(). To use this function, +you determine the root set yourself, and this function finds all other +unreferenced objects and deletes them.

    +

    Use this API when you want to perform more selective pruning - for example, +retain all commits from a production branch, but just GC some history from +your dev branch.

    +

    The OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE flag may be specified to just determine +statistics on objects that would be deleted, without actually deleting them.

    +

    Locking: exclusive

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    options

    Options controlling prune process

     

    out_objects_total

    Number of objects found.

    [out]

    out_objects_pruned

    Number of objects deleted.

    [out]

    out_pruned_object_size_total

    Storage size in bytes of objects deleted.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2017.1

    +
    +
    +
    +

    ostree_repo_pull ()

    +
    gboolean
    +ostree_repo_pull (OstreeRepo *self,
    +                  const char *remote_name,
    +                  char **refs_to_fetch,
    +                  OstreeRepoPullFlags flags,
    +                  OstreeAsyncProgress *progress,
    +                  GCancellable *cancellable,
    +                  GError **error);
    +

    Connect to the remote repository, fetching the specified set of +refs refs_to_fetch +. For each ref that is changed, download the +commit, all metadata, and all content objects, storing them safely +on disk in self +.

    +

    If flags + contains OSTREE_REPO_PULL_FLAGS_MIRROR, and +the refs_to_fetch + is NULL, and the remote repository contains a +summary file, then all refs will be fetched.

    +

    If flags + contains OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY, then only the +metadata for the commits in refs_to_fetch + is pulled.

    +

    Warning: This API will iterate the thread default main context, +which is a bug, but kept for compatibility reasons. If you want to +avoid this, use g_main_context_push_thread_default() to push a new +one around this call.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of remote

     

    refs_to_fetch

    Optional list of +refs; if NULL, fetch all configured refs.

    [array zero-terminated=1][element-type utf8][allow-none]

    flags

    Options controlling fetch behavior

     

    progress

    Progress.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_pull_one_dir ()

    +
    gboolean
    +ostree_repo_pull_one_dir (OstreeRepo *self,
    +                          const char *remote_name,
    +                          const char *dir_to_pull,
    +                          char **refs_to_fetch,
    +                          OstreeRepoPullFlags flags,
    +                          OstreeAsyncProgress *progress,
    +                          GCancellable *cancellable,
    +                          GError **error);
    +

    This is similar to ostree_repo_pull(), but only fetches a single +subpath.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of remote

     

    dir_to_pull

    Subdirectory path

     

    refs_to_fetch

    Optional list of +refs; if NULL, fetch all configured refs.

    [array zero-terminated=1][element-type utf8][allow-none]

    flags

    Options controlling fetch behavior

     

    progress

    Progress.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_pull_with_options ()

    +
    gboolean
    +ostree_repo_pull_with_options (OstreeRepo *self,
    +                               const char *remote_name_or_baseurl,
    +                               GVariant *options,
    +                               OstreeAsyncProgress *progress,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    Like ostree_repo_pull(), but supports an extensible set of flags. +The following are currently defined:

    +
      +
    • refs (as): Array of string refs

    • +
    • collection-refs (a(sss)): Array of (collection ID, ref name, checksum) tuples to pull; +mutually exclusive with refs and override-commit-ids. Checksums may be the empty +string to pull the latest commit for that ref

    • +
    • flags (i): An instance of OstreeRepoPullFlags

    • +
    • subdir (s): Pull just this subdirectory

    • +
    • subdirs (as): Pull just these subdirectories

    • +
    • override-remote-name (s): If local, add this remote to refspec

    • +
    • gpg-verify (b): GPG verify commits

    • +
    • gpg-verify-summary (b): GPG verify summary

    • +
    • disable-sign-verify (b): Disable signapi verification of commits

    • +
    • disable-sign-verify-summary (b): Disable signapi verification of the summary

    • +
    • depth (i): How far in the history to traverse; default is 0, -1 means infinite

    • +
    • per-object-fsync (b): Perform disk writes more slowly, avoiding a single large I/O sync

    • +
    • disable-static-deltas (b): Do not use static deltas

    • +
    • require-static-deltas (b): Require static deltas

    • +
    • override-commit-ids (as): Array of specific commit IDs to fetch for refs

    • +
    • timestamp-check (b): Verify commit timestamps are newer than current (when pulling via +ref); Since: 2017.11

    • +
    • timestamp-check-from-rev (s): Verify that all fetched commit timestamps are newer than +timestamp of given rev; Since: 2020.4

    • +
    • max-metadata-size (t): Restrict metadata objects to a maximum number of bytes; 0 to +disable. Since: 2018.9

    • +
    • dry-run (b): Only print information on what will be downloaded (requires static deltas)

    • +
    • override-url (s): Fetch objects from this URL if remote specifies no metalink in options

    • +
    • inherit-transaction (b): Don't initiate, finish or abort a transaction, useful to do +multiple pulls in one transaction.

    • +
    • http-headers (a(ss)): Additional headers to add to all HTTP requests

    • +
    • update-frequency (u): Frequency to call the async progress callback in milliseconds, if +any; only values higher than 0 are valid

    • +
    • localcache-repos (as): File paths for local repos to use as caches when doing remote +fetches

    • +
    • append-user-agent (s): Additional string to append to the user agent

    • +
    • n-network-retries (u): Number of times to retry each download on receiving +a transient network error, such as a socket timeout; default is 5, 0 +means return errors without retrying. Since: 2018.6

    • +
    • low-speed-limit-bytes (u): The average transfer speed per second of a transfer + during the time set via "low-speed-time-seconds" for libcurl to abort.

    • +
    • low-speed-time-seconds (u): The time in number seconds that the transfer + speed should be below the "low-speed-limit-bytes" setting for libcurl to abort.

    • +
    • retry-all-network-errors (b): Retry when network issues happen, instead of + failing automatically. Currently only affects libcurl. (Default set to true)

    • +
    • max-outstanding-fetcher-requests (u): The max amount of concurrent connections allowed.

    • +
    • ref-keyring-map (a(sss)): Array of (collection ID, ref name, keyring +remote name) tuples specifying which remote's keyring should be used when +doing GPG verification of each collection-ref. This is useful to prevent a +remote from serving malicious updates to refs which did not originate from +it. This can be a subset or superset of the refs being pulled; any ref +not being pulled will be ignored and any ref without a keyring remote +will be verified with the keyring of the remote being pulled from.

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name_or_baseurl

    Name of remote or file:// url

     

    options

    A GVariant a{sv} with an extensible set of flags.

     

    progress

    Progress.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.9

    +
    +
    +
    +

    ostree_repo_pull_default_console_progress_changed ()

    +
    void
    +ostree_repo_pull_default_console_progress_changed
    +                               (OstreeAsyncProgress *progress,
    +                                gpointer user_data);
    +

    Convenient "changed" callback for use with +ostree_async_progress_new_and_connect() when pulling from a remote +repository.

    +

    Depending on the state of the OstreeAsyncProgress, either displays a +custom status message, or else outstanding fetch progress in bytes/sec, +or else outstanding content or metadata writes to the repository in +number of objects.

    +

    Compatibility note: this function previously assumed that user_data + +was a pointer to a GSConsole instance. This is no longer the case, +and user_data + is ignored.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    progress

    Async progress

     

    user_data

    User data.

    [allow-none]
    +
    +
    +
    +
    +

    ostree_repo_sign_commit ()

    +
    gboolean
    +ostree_repo_sign_commit (OstreeRepo *self,
    +                         const gchar *commit_checksum,
    +                         const gchar *key_id,
    +                         const gchar *homedir,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Add a GPG signature to a commit.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    commit_checksum

    SHA256 of given commit to sign

     

    key_id

    Use this GPG key id

     

    homedir

    GPG home directory, or NULL.

    [allow-none]

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_repo_append_gpg_signature ()

    +
    gboolean
    +ostree_repo_append_gpg_signature (OstreeRepo *self,
    +                                  const gchar *commit_checksum,
    +                                  GBytes *signature_bytes,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Append a GPG signature to a commit.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    commit_checksum

    SHA256 of given commit to sign

     

    signature_bytes

    Signature data

     

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_repo_add_gpg_signature_summary ()

    +
    gboolean
    +ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
    +                                       const gchar **key_id,
    +                                       const gchar *homedir,
    +                                       GCancellable *cancellable,
    +                                       GError **error);
    +

    Add a GPG signature to a summary file.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    key_id

    NULL-terminated array of GPG keys.

    [array zero-terminated=1][element-type utf8]

    homedir

    GPG home directory, or NULL.

    [allow-none]

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +
    +
    +

    ostree_repo_gpg_sign_data ()

    +
    gboolean
    +ostree_repo_gpg_sign_data (OstreeRepo *self,
    +                           GBytes *data,
    +                           GBytes *old_signatures,
    +                           const gchar **key_id,
    +                           const gchar *homedir,
    +                           GBytes **out_signatures,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Sign the given data + with the specified keys in key_id +. Similar to +ostree_repo_add_gpg_signature_summary() but can be used on any +data.

    +

    You can use ostree_repo_gpg_verify_data() to verify the signatures.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    data

    Data as a GBytes

     

    old_signatures

    Existing signatures to append to (or NULL).

    [nullable]

    key_id

    NULL-terminated array of GPG keys.

    [array zero-terminated=1][element-type utf8]

    homedir

    GPG home directory, or NULL.

    [nullable]

    out_signatures

    in case of success will contain signature.

    [out]

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE if data +has been signed successfully, +FALSE in case of error (error +will contain the reason).

    +
    +

    Since: 2020.8

    +
    +
    +
    +

    ostree_repo_gpg_verify_data ()

    +
    OstreeGpgVerifyResult *
    +ostree_repo_gpg_verify_data (OstreeRepo *self,
    +                             const gchar *remote_name,
    +                             GBytes *data,
    +                             GBytes *signatures,
    +                             GFile *keyringdir,
    +                             GFile *extra_keyring,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +

    Verify signatures + for data + using GPG keys in the keyring for +remote_name +, and return an OstreeGpgVerifyResult.

    +

    The remote_name + parameter can be NULL. In that case it will do +the verifications using GPG keys in the keyrings of all remotes.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repository

     

    remote_name

    Name of remote.

    [nullable]

    data

    Data as a GBytes

     

    signatures

    Signatures as a GBytes

     

    keyringdir

    Path to directory GPG keyrings; overrides built-in default if given.

    [nullable]

    extra_keyring

    Path to additional keyring file (not a directory).

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    an OstreeGpgVerifyResult, or NULL on error.

    +

    [transfer full]

    +
    +

    Since: 2016.6

    +
    +
    +
    +

    ostree_repo_signature_verify_commit_data ()

    +
    gboolean
    +ostree_repo_signature_verify_commit_data
    +                               (OstreeRepo *self,
    +                                const char *remote_name,
    +                                GBytes *commit_data,
    +                                GBytes *commit_metadata,
    +                                OstreeRepoVerifyFlags flags,
    +                                char **out_results,
    +                                GError **error);
    +

    Validate the commit data using the commit metadata which must +contain at least one valid signature. If GPG and signapi are +both enabled, then both must find at least one valid signature.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of remote

     

    commit_data

    Commit object data (GVariant)

     

    commit_metadata

    Commit metadata (GVariant a{sv}), must contain at least one valid signature

     

    flags

    Optionally disable GPG or signapi

     

    out_results

    Textual description of results.

    [optional][out][transfer full]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_verify_commit ()

    +
    gboolean
    +ostree_repo_verify_commit (OstreeRepo *self,
    +                           const gchar *commit_checksum,
    +                           GFile *keyringdir,
    +                           GFile *extra_keyring,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Check for a valid GPG signature on commit named by the ASCII +checksum commit_checksum +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repository

     

    commit_checksum

    ASCII SHA256 checksum

     

    keyringdir

    Path to directory GPG keyrings; overrides built-in default if given.

    [allow-none]

    extra_keyring

    Path to additional keyring file (not a directory).

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE if there was a GPG signature from a trusted keyring, otherwise FALSE

    +
    +
    +
    +
    +

    ostree_repo_verify_commit_ext ()

    +
    OstreeGpgVerifyResult *
    +ostree_repo_verify_commit_ext (OstreeRepo *self,
    +                               const gchar *commit_checksum,
    +                               GFile *keyringdir,
    +                               GFile *extra_keyring,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    Read GPG signature(s) on the commit named by the ASCII checksum +commit_checksum + and return detailed results.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repository

     

    commit_checksum

    ASCII SHA256 checksum

     

    keyringdir

    Path to directory GPG keyrings; overrides built-in default if given.

    [allow-none]

    extra_keyring

    Path to additional keyring file (not a directory).

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    an OstreeGpgVerifyResult, or NULL on error.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_verify_commit_for_remote ()

    +
    OstreeGpgVerifyResult *
    +ostree_repo_verify_commit_for_remote (OstreeRepo *self,
    +                                      const gchar *commit_checksum,
    +                                      const gchar *remote_name,
    +                                      GCancellable *cancellable,
    +                                      GError **error);
    +

    Read GPG signature(s) on the commit named by the ASCII checksum +commit_checksum + and return detailed results, based on the keyring +configured for remote +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repository

     

    commit_checksum

    ASCII SHA256 checksum

     

    remote_name

    OSTree remote to use for configuration

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    an OstreeGpgVerifyResult, or NULL on error.

    +

    [transfer full]

    +
    +

    Since: 2016.14

    +
    +
    +
    +

    ostree_repo_verify_summary ()

    +
    OstreeGpgVerifyResult *
    +ostree_repo_verify_summary (OstreeRepo *self,
    +                            const char *remote_name,
    +                            GBytes *summary,
    +                            GBytes *signatures,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Verify signatures + for summary + data using GPG keys in the keyring for +remote_name +, and return an OstreeGpgVerifyResult.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    remote_name

    Name of remote

     

    summary

    Summary data as a GBytes

     

    signatures

    Summary signatures as a GBytes

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    an OstreeGpgVerifyResult, or NULL on error.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_repo_regenerate_metadata ()

    +
    gboolean
    +ostree_repo_regenerate_metadata (OstreeRepo *self,
    +                                 GVariant *additional_metadata,
    +                                 GVariant *options,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Regenerate the OSTree repository metadata used by clients to describe +available branches and other metadata.

    +

    The repository metadata currently consists of the summary file. See +ostree_repo_regenerate_summary() and OSTREE_SUMMARY_GVARIANT_FORMAT for +additional details on its contents.

    +

    Additionally, if the core/collection-id key is set in the configuration, a +OSTREE_REPO_METADATA_REF commit will be created.

    +

    The following options + are currently defined:

    +
      +
    • gpg-key-ids (as): Array of GPG key IDs to sign the metadata with.

    • +
    • gpg-homedir (s): GPG home directory.

    • +
    • sign-keys (av): Array of keys to sign the metadata with. The key +type is specific to the sign engine used.

    • +
    • sign-type (s): Sign engine type to use. If not specified, +OSTREE_SIGN_NAME_ED25519 is used.

    • +
    +

    Locking: shared

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    additional_metadata

    A GVariant a{sv}, or NULL.

    [nullable]

    options

    A GVariant a{sv} with an extensible set of flags.

    [nullable]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2023.1

    +
    +
    +
    +

    ostree_repo_regenerate_summary ()

    +
    gboolean
    +ostree_repo_regenerate_summary (OstreeRepo *self,
    +                                GVariant *additional_metadata,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    An OSTree repository can contain a high level "summary" file that +describes the available branches and other metadata.

    +

    If the timetable for making commits and updating the summary file is fairly +regular, setting the ostree.summary.expires key in additional_metadata + +will aid clients in working out when to check for updates.

    +

    It is regenerated automatically after any ref is +added, removed, or updated if core/auto-update-summary is set.

    +

    If the core/collection-id key is set in the configuration, it will be +included as OSTREE_SUMMARY_COLLECTION_ID in the summary file. Refs that +have associated collection IDs will be included in the generated summary +file, listed under the OSTREE_SUMMARY_COLLECTION_MAP key. Collection IDs +and refs in OSTREE_SUMMARY_COLLECTION_MAP are guaranteed to be in +lexicographic order.

    +

    Locking: shared (Prior to 2021.7, this was exclusive)

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Repo

     

    additional_metadata

    A GVariant of type a{sv}, or NULL.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeRepo

    +
    typedef struct OstreeRepo OstreeRepo;
    +
    +

    Private instance structure.

    +
    +
    +
    +

    enum OstreeRepoMode

    +

    See the documentation of OstreeRepo for more information about the +possible modes.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_MODE_BARE

    +

    Files are stored as themselves; checkouts are hardlinks; can only be +written as root

    +
     

    OSTREE_REPO_MODE_ARCHIVE

    +

    Files are compressed, should be owned by non-root. Can be served via +HTTP. Since: 2017.12

    +
     

    OSTREE_REPO_MODE_ARCHIVE_Z2

    +

    Legacy alias for OSTREE_REPO_MODE_ARCHIVE

    +
     

    OSTREE_REPO_MODE_BARE_USER

    +

    Files are stored as themselves, except ownership; can be written by +user. Hardlinks work only in user checkouts.

    +
     

    OSTREE_REPO_MODE_BARE_USER_ONLY

    +

    Same as BARE_USER, but all metadata is not stored, so it can +only be used for user checkouts. Does not need xattrs.

    +
     

    OSTREE_REPO_MODE_BARE_SPLIT_XATTRS

    +

    Same as BARE_USER, but xattrs are stored separately from +file content, with dedicated object types.

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoLockType

    +

    Flags controlling repository locking.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_REPO_LOCK_SHARED

    +

    A "read only" lock; multiple readers are allowed.

    +
     

    OSTREE_REPO_LOCK_EXCLUSIVE

    +

    A writable lock at most one writer can be active, and zero readers.

    +
     
    +
    +

    Since: 2021.3

    +
    +
    +
    +

    OstreeRepoAutoLock

    +
    typedef struct OstreeRepoAutoLock OstreeRepoAutoLock;
    +
    +

    An opaque type for use with ostree_repo_auto_lock_push().

    +

    Since: 2021.3

    +
    +
    +
    +

    enum OstreeRepoRemoteChange

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_REMOTE_CHANGE_ADD

    +

    Add a remote

    +
     

    OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS

    +

    Like above, but do nothing if the remote exists

    +
     

    OSTREE_REPO_REMOTE_CHANGE_DELETE

    +

    Delete a remote

    +
     

    OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS

    +

    Delete a remote, do nothing if the remote does not +exist

    +
     

    OSTREE_REPO_REMOTE_CHANGE_REPLACE

    +

    Add or replace a remote (Since: 2019.2)

    +
     
    +
    +
    +
    +
    +

    struct OstreeRepoTransactionStats

    +
    struct OstreeRepoTransactionStats {
    +  guint metadata_objects_total;
    +  guint metadata_objects_written;
    +  guint content_objects_total;
    +  guint content_objects_written;
    +  guint64 content_bytes_written;
    +  guint devino_cache_hits;
    +
    +  guint padding1;
    +  guint64 padding2;
    +  guint64 padding3;
    +  guint64 padding4;
    +};
    +
    +

    A list of statistics for each transaction that may be +interesting for reporting purposes.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    guint metadata_objects_total;

    The total number of metadata objects +in the repository after this transaction has completed.

     

    guint metadata_objects_written;

    The number of metadata objects that +were written to the repository in this transaction.

     

    guint content_objects_total;

    The total number of content objects +in the repository after this transaction has completed.

     

    guint content_objects_written;

    The number of content objects that +were written to the repository in this transaction.

     

    guint64 content_bytes_written;

    The amount of data added to the repository, +in bytes, counting only content objects.

     

    guint devino_cache_hits;

      

    guint padding1;

    reserved

     

    guint64 padding2;

    reserved

     

    guint64 padding3;

    reserved

     

    guint64 padding4;

    reserved

     
    +
    +
    +
    +
    +

    enum OstreeRepoResolveRevExtFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_REPO_RESOLVE_REV_EXT_NONE

    +

    No flags.

    +
     

    OSTREE_REPO_RESOLVE_REV_EXT_LOCAL_ONLY

    +

    Exclude remote and mirrored refs. Since: 2019.2

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoListRefsExtFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_LIST_REFS_EXT_NONE

    +

    No flags.

    +
     

    OSTREE_REPO_LIST_REFS_EXT_ALIASES

    +

    Only list aliases. Since: 2017.10

    +
     

    OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_REMOTES

    +

    Exclude remote refs. Since: 2017.11

    +
     

    OSTREE_REPO_LIST_REFS_EXT_EXCLUDE_MIRRORS

    +

    Exclude mirrored refs. Since: 2019.2

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoCommitState

    +

    Flags representing the state of a commit in the local repository, as returned +by ostree_repo_load_commit().

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_COMMIT_STATE_NORMAL

    +

    Commit is complete. This is the default. +(Since: 2017.14.)

    +
     

    OSTREE_REPO_COMMIT_STATE_PARTIAL

    +

    One or more objects are missing from the +local copy of the commit, but metadata is present. (Since: 2015.7.)

    +
     

    OSTREE_REPO_COMMIT_STATE_FSCK_PARTIAL

    +

    One or more objects are missing from the +local copy of the commit, due to an fsck --delete. (Since: 2019.4.)

    +
     
    +
    +

    Since: 2015.7

    +
    +
    +
    +

    enum OstreeRepoCommitFilterResult

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_REPO_COMMIT_FILTER_ALLOW

    +

    Do commit this object

    +
     

    OSTREE_REPO_COMMIT_FILTER_SKIP

    +

    Ignore this object

    +
     
    +
    +
    +
    +
    +

    OstreeRepoCommitModifier

    +
    typedef struct OstreeRepoCommitModifier OstreeRepoCommitModifier;
    +
    +

    A structure allowing control over commits.

    +
    +
    +
    +

    enum OstreeRepoCommitModifierFlags

    +

    Flags modifying commit behavior. In bare-user-only mode, +OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS + and +OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS + are automatically enabled.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_NONE

    +

    No special flags

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS

    +

    Do not process extended attributes

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES

    +

    Generate size information.

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CANONICAL_PERMISSIONS

    +

    Canonicalize permissions.

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_ERROR_ON_UNLABELED

    +

    Emit an error if configured SELinux +policy does not provide a label

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_CONSUME

    +

    Delete added files/directories after commit; Since: +2017.13

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_DEVINO_CANONICAL

    +

    If a devino cache hit is found, skip +modifier filters (non-directories only); Since: 2017.14

    +
     

    OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SELINUX_LABEL_V1

    +

    For SELinux and other systems, label +/usr/etc as if it was /etc.

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoCheckoutMode

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_REPO_CHECKOUT_MODE_NONE

    +

    No special options

    +
     

    OSTREE_REPO_CHECKOUT_MODE_USER

    +

    Ignore uid/gid of files

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoCheckoutOverwriteMode

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_CHECKOUT_OVERWRITE_NONE

    +

    No special options

    +
     

    OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES

    +

    When layering checkouts, unlink() and replace +existing files, but do not modify existing directories (unless whiteouts are enabled, then +directories are replaced)

    +
     

    OSTREE_REPO_CHECKOUT_OVERWRITE_ADD_FILES

    +

    Only add new files/directories

    +
     

    OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_IDENTICAL

    +

    Like UNION_FILES, but error if files are not +identical (requires hardlink checkouts)

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoListObjectsFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_LIST_OBJECTS_LOOSE

    +

    List only loose (plain file) objects

    +
     

    OSTREE_REPO_LIST_OBJECTS_PACKED

    +

    List only packed (compacted into blobs) objects

    +
     

    OSTREE_REPO_LIST_OBJECTS_ALL

    +

    List all objects

    +
     

    OSTREE_REPO_LIST_OBJECTS_NO_PARENTS

    +

    Only list objects in this repo, not parents

    +
     
    +
    +
    +
    +
    +

    OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE

    +
    #define OSTREE_REPO_LIST_OBJECTS_VARIANT_TYPE (G_VARIANT_TYPE ("(bas)")
    +
    +

    b - TRUE if object is available "loose" +as - List of pack file checksums in which this object appears

    +
    +
    +
    +

    enum OstreeStaticDeltaGenerateOpt

    +

    Parameters controlling optimization of static deltas.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_STATIC_DELTA_GENERATE_OPT_LOWLATENCY

    +

    Optimize for speed of delta creation over space

    +
     

    OSTREE_STATIC_DELTA_GENERATE_OPT_MAJOR

    +

    Optimize for delta size (may be very slow)

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoCommitTraverseFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_REPO_COMMIT_TRAVERSE_FLAG_NONE

    +

    No special options for traverse

    +
     

    OSTREE_REPO_COMMIT_TRAVERSE_FLAG_COMMIT_ONLY

    +

    Traverse and retrieve only commit objects. +(Since: 2022.2)

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoCommitIterResult

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_COMMIT_ITER_RESULT_ERROR

      

    OSTREE_REPO_COMMIT_ITER_RESULT_END

      

    OSTREE_REPO_COMMIT_ITER_RESULT_FILE

      

    OSTREE_REPO_COMMIT_ITER_RESULT_DIR

      
    +
    +
    +
    +
    +

    enum OstreeRepoPruneFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_PRUNE_FLAGS_NONE

    +

    No special options for pruning

    +
     

    OSTREE_REPO_PRUNE_FLAGS_NO_PRUNE

    +

    Don't actually delete objects

    +
     

    OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY

    +

    Do not traverse individual commit objects, only follow refs +for reachability calculations

    +
     

    OSTREE_REPO_PRUNE_FLAGS_COMMIT_ONLY

    +

    Only traverse commit objects. (Since 2022.2)

    +
     
    +
    +
    +
    +
    +

    enum OstreeRepoPullFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_REPO_PULL_FLAGS_NONE

    +

    No special options for pull

    +
     

    OSTREE_REPO_PULL_FLAGS_MIRROR

    +

    Write out refs suitable for mirrors and fetch all refs if none +requested

    +
     

    OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY

    +

    Fetch only the commit metadata

    +
     

    OSTREE_REPO_PULL_FLAGS_UNTRUSTED

    +

    Do verify checksums of local (filesystem-accessible) +repositories (defaults on for HTTP)

    +
     

    OSTREE_REPO_PULL_FLAGS_BAREUSERONLY_FILES

    +

    Since 2017.7. Reject writes of content objects with +modes outside of 0775.

    +
     

    OSTREE_REPO_PULL_FLAGS_TRUSTED_HTTP

    +

    Don't verify checksums of objects HTTP repositories +(Since: 2017.12)

    +
     
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-Progress-notification-system-for-asynchronous-operations.html b/reference/ostree-Progress-notification-system-for-asynchronous-operations.html new file mode 100644 index 0000000000..b0229a41ad --- /dev/null +++ b/reference/ostree-Progress-notification-system-for-asynchronous-operations.html @@ -0,0 +1,623 @@ + + + + +Progress notification system for asynchronous operations: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Progress notification system for asynchronous operations

    +

    Progress notification system for asynchronous operations — Values representing progress

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeAsyncProgress * + +ostree_async_progress_new () +
    +OstreeAsyncProgress * + +ostree_async_progress_new_and_connect () +
    +void + +ostree_async_progress_copy_state () +
    +char * + +ostree_async_progress_get_status () +
    +void + +ostree_async_progress_get () +
    +GVariant * + +ostree_async_progress_get_variant () +
    +guint + +ostree_async_progress_get_uint () +
    +guint64 + +ostree_async_progress_get_uint64 () +
    +void + +ostree_async_progress_set_status () +
    +void + +ostree_async_progress_set () +
    +void + +ostree_async_progress_set_variant () +
    +void + +ostree_async_progress_set_uint () +
    +void + +ostree_async_progress_set_uint64 () +
    +void + +ostree_async_progress_finish () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    typedefOstreeAsyncProgress
    +
    +
    +

    Description

    +

    For many asynchronous operations, it's desirable for callers to be +able to watch their status as they progress. For example, an user +interface calling an asynchronous download operation will want to +be able to see the total number of bytes downloaded.

    +

    This class provides a mechanism for callees of asynchronous +operations to communicate back with callers. It transparently +handles thread safety, ensuring that the progress change +notification occurs in the thread-default context of the calling +operation.

    +

    The ostree_async_progress_get_status() and ostree_async_progress_set_status() +methods get and set a well-known status key of type G_VARIANT_TYPE_STRING. +This key may be accessed using the other OstreeAsyncProgress methods, but it +must always have the correct type.

    +
    +
    +

    Functions

    +
    +

    ostree_async_progress_new ()

    +
    OstreeAsyncProgress *
    +ostree_async_progress_new (void);
    +
    +

    Returns

    +

    A new progress object.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_async_progress_new_and_connect ()

    +
    OstreeAsyncProgress *
    +ostree_async_progress_new_and_connect (void (*changed) (OstreeAsyncProgress *self, gpointer user_data),
    +                                       gpointer user_data);
    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    changed

    a notification callback

     

    user_data

    data to pass to changed +

     
    +
    +
    +

    Returns

    +

    A new progress object.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_async_progress_copy_state ()

    +
    void
    +ostree_async_progress_copy_state (OstreeAsyncProgress *self,
    +                                  OstreeAsyncProgress *dest);
    +

    Atomically copies all the state from self + to dest +, without invoking the +callback. +This is used for proxying progress objects across different GMainContexts.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    An OstreeAsyncProgress to copy from

     

    dest

    An OstreeAsyncProgress to copy to

     
    +
    +

    Since: 2019.6

    +
    +
    +
    +

    ostree_async_progress_get_status ()

    +
    char *
    +ostree_async_progress_get_status (OstreeAsyncProgress *self);
    +

    Get the human-readable status string from the OstreeAsyncProgress. This +operation is thread-safe. The retuned value may be NULL if no status is +set.

    +

    This is a convenience function to get the well-known status key.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeAsyncProgress

     
    +
    +
    +

    Returns

    +

    the current status, or NULL if none is set.

    +

    [transfer full][nullable]

    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_get ()

    +
    void
    +ostree_async_progress_get (OstreeAsyncProgress *self,
    +                           ...);
    +

    Get the values corresponding to zero or more keys from the +OstreeAsyncProgress. Each key is specified in @... as the key name, followed +by a GVariant format string, followed by the necessary arguments for that +format string, just as for g_variant_get(). After those arguments is the +next key name. The varargs list must be NULL-terminated.

    +

    Each format string must make deep copies of its value, as the values stored +in the OstreeAsyncProgress may be freed from another thread after this +function returns.

    +

    This operation is thread-safe, and all the keys are queried atomically.

    +
    + + + + + + + +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    +10
    +11
    guint32 outstanding_fetches;
    +guint64 bytes_received;
    +g_autofree gchar *status = NULL;
    +g_autoptr(GVariant) refs_variant = NULL;
    +
    +ostree_async_progress_get (progress,
    +                           "outstanding-fetches", "u", &outstanding_fetches,
    +                           "bytes-received", "t", &bytes_received,
    +                           "status", "s", &status,
    +                           "refs", "@a{ss}", &refs_variant,
    +                           NULL);
    +
    + +

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    an OstreeAsyncProgress

     

    ...

    key name, format string, GVariant return locations, …, followed by NULL

     
    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_get_variant ()

    +
    GVariant *
    +ostree_async_progress_get_variant (OstreeAsyncProgress *self,
    +                                   const char *key);
    +

    Look up a key in the OstreeAsyncProgress and return the GVariant associated +with it. The lookup is thread-safe.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    an OstreeAsyncProgress

     

    key

    a key to look up

     
    +
    +
    +

    Returns

    +

    value for the given key +, or NULL if +it was not set.

    +

    [transfer full][nullable]

    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_get_uint ()

    +
    guint
    +ostree_async_progress_get_uint (OstreeAsyncProgress *self,
    +                                const char *key);
    +
    +
    +
    +

    ostree_async_progress_get_uint64 ()

    +
    guint64
    +ostree_async_progress_get_uint64 (OstreeAsyncProgress *self,
    +                                  const char *key);
    +
    +
    +
    +

    ostree_async_progress_set_status ()

    +
    void
    +ostree_async_progress_set_status (OstreeAsyncProgress *self,
    +                                  const char *status);
    +

    Set the human-readable status string for the OstreeAsyncProgress. This +operation is thread-safe. NULL may be passed to clear the status.

    +

    This is a convenience function to set the well-known status key.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    an OstreeAsyncProgress

     

    status

    new status string, or NULL to clear the status.

    [nullable]
    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_set ()

    +
    void
    +ostree_async_progress_set (OstreeAsyncProgress *self,
    +                           ...);
    +

    Set the values for zero or more keys in the OstreeAsyncProgress. Each key is +specified in @... as the key name, followed by a GVariant format string, +followed by the necessary arguments for that format string, just as for +g_variant_new(). After those arguments is the next key name. The varargs list +must be NULL-terminated.

    +

    g_variant_ref_sink() will be called as appropriate on the GVariant +parameters, so they may be floating.

    +

    This operation is thread-safe, and all the keys are set atomically.

    +
    + + + + + + + +
    1
    +2
    +3
    +4
    +5
    +6
    +7
    +8
    +9
    guint32 outstanding_fetches = 15;
    +guint64 bytes_received = 1000;
    +
    +ostree_async_progress_set (progress,
    +                           "outstanding-fetches", "u", outstanding_fetches,
    +                           "bytes-received", "t", bytes_received,
    +                           "status", "s", "Updated status",
    +                           "refs", "@a{ss}", g_variant_new_parsed ("@a{ss} {}"),
    +                           NULL);
    +
    + +

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    an OstreeAsyncProgress

     

    ...

    key name, format string, GVariant parameters, …, followed by NULL

     
    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_set_variant ()

    +
    void
    +ostree_async_progress_set_variant (OstreeAsyncProgress *self,
    +                                   const char *key,
    +                                   GVariant *value);
    +

    Assign a new value + to the given key +, replacing any existing value. The +operation is thread-safe. value + may be a floating reference; +g_variant_ref_sink() will be called on it.

    +

    Any watchers of the OstreeAsyncProgress will be notified of the change if +value + differs from the existing value for key +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeAsyncProgress

     

    key

    a key to set

     

    value

    the value to assign to key +

     
    +
    +

    Since: 2017.6

    +
    +
    +
    +

    ostree_async_progress_set_uint ()

    +
    void
    +ostree_async_progress_set_uint (OstreeAsyncProgress *self,
    +                                const char *key,
    +                                guint value);
    +
    +
    +
    +

    ostree_async_progress_set_uint64 ()

    +
    void
    +ostree_async_progress_set_uint64 (OstreeAsyncProgress *self,
    +                                  const char *key,
    +                                  guint64 value);
    +
    +
    +
    +

    ostree_async_progress_finish ()

    +
    void
    +ostree_async_progress_finish (OstreeAsyncProgress *self);
    +

    Process any pending signals, ensuring the main context is cleared +of sources used by this object. Also ensures that no further +events will be queued.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Self

     
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeAsyncProgress

    +
    typedef struct OstreeAsyncProgress OstreeAsyncProgress;
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-Root-partition-mount-point.html b/reference/ostree-Root-partition-mount-point.html new file mode 100644 index 0000000000..28f2b9315d --- /dev/null +++ b/reference/ostree-Root-partition-mount-point.html @@ -0,0 +1,2586 @@ + + + + +Root partition mount point: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Root partition mount point

    +

    Root partition mount point — Manage physical root filesystem

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeSysroot * + +ostree_sysroot_new () +
    +OstreeSysroot * + +ostree_sysroot_new_default () +
    +gboolean + +ostree_sysroot_initialize () +
    +gboolean + +ostree_sysroot_initialize_with_mount_namespace () +
    +GFile * + +ostree_sysroot_get_path () +
    +gboolean + +ostree_sysroot_load () +
    +gboolean + +ostree_sysroot_load_if_changed () +
    +gboolean + +ostree_sysroot_lock () +
    +gboolean + +ostree_sysroot_try_lock () +
    +void + +ostree_sysroot_lock_async () +
    +gboolean + +ostree_sysroot_lock_finish () +
    +void + +ostree_sysroot_unlock () +
    +void + +ostree_sysroot_unload () +
    +gboolean + +ostree_sysroot_update_post_copy () +
    +void + +ostree_sysroot_set_mount_namespace_in_use () +
    +gboolean + +ostree_sysroot_is_booted () +
    +int + +ostree_sysroot_get_fd () +
    +gboolean + +ostree_sysroot_ensure_initialized () +
    +int + +ostree_sysroot_get_bootversion () +
    +int + +ostree_sysroot_get_subbootversion () +
    +GPtrArray * + +ostree_sysroot_get_deployments () +
    +OstreeDeployment * + +ostree_sysroot_get_booted_deployment () +
    +OstreeDeployment * + +ostree_sysroot_require_booted_deployment () +
    +GFile * + +ostree_sysroot_get_deployment_directory () +
    +char * + +ostree_sysroot_get_deployment_dirpath () +
    +GFile * + +ostree_sysroot_get_deployment_origin_path () +
    +gboolean + +ostree_sysroot_cleanup () +
    +gboolean + +ostree_sysroot_prepare_cleanup () +
    +gboolean + +ostree_sysroot_cleanup_prune_repo () +
    +OstreeRepo * + +ostree_sysroot_repo () +
    +gboolean + +ostree_sysroot_get_repo () +
    +OstreeDeployment * + +ostree_sysroot_get_staged_deployment () +
    +gboolean + +ostree_sysroot_init_osname () +
    +gboolean + +ostree_sysroot_deployment_set_kargs () +
    +gboolean + +ostree_sysroot_deployment_set_kargs_in_place () +
    +gboolean + +ostree_sysroot_deployment_set_mutable () +
    +gboolean + +ostree_sysroot_deployment_unlock () +
    +gboolean + +ostree_sysroot_deployment_set_pinned () +
    +gboolean + +ostree_sysroot_write_deployments () +
    +gboolean + +ostree_sysroot_write_deployments_with_options () +
    +gboolean + +ostree_sysroot_write_origin_file () +
    +gboolean + +ostree_sysroot_stage_tree () +
    +gboolean + +ostree_sysroot_stage_tree_with_options () +
    +gboolean + +ostree_sysroot_stage_overlay_initrd () +
    +gboolean + +ostree_sysroot_change_finalization () +
    +gboolean + +ostree_sysroot_deploy_tree () +
    +gboolean + +ostree_sysroot_deploy_tree_with_options () +
    +OstreeDeployment * + +ostree_sysroot_get_merge_deployment () +
    +void + +ostree_sysroot_query_deployments_for () +
    +GKeyFile * + +ostree_sysroot_origin_new_from_refspec () +
    +gboolean + +ostree_sysroot_simple_write_deployment () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + +
    typedefOstreeSysroot
    enumOstreeSysrootSimpleWriteDeploymentFlags
    +
    +
    +

    Description

    +

    A OstreeSysroot object represents a physical root filesystem, +which in particular should contain a toplevel /ostree directory. +Inside this directory is an OstreeRepo in /ostree/repo, plus a set +of deployments in /ostree/deploy.

    +

    This class is not by default safe against concurrent use by threads +or external processes. You can use ostree_sysroot_lock() to +perform locking externally.

    +
    +
    +

    Functions

    +
    +

    ostree_sysroot_new ()

    +
    OstreeSysroot *
    +ostree_sysroot_new (GFile *path);
    +

    Create a new OstreeSysroot object for the sysroot at path +. If path + is NULL, +the current visible root file system is used, equivalent to +ostree_sysroot_new_default().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    path

    Path to a system root directory, or NULL to use the +current visible root file system.

    [allow-none]
    +
    +
    +

    Returns

    +

    An accessor object for an system root located at path +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_new_default ()

    +
    OstreeSysroot *
    +ostree_sysroot_new_default (void);
    +
    +

    Returns

    +

    An accessor for the current visible root / filesystem.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_initialize ()

    +
    gboolean
    +ostree_sysroot_initialize (OstreeSysroot *self,
    +                           GError **error);
    +

    Subset of ostree_sysroot_load(); performs basic initialization. Notably, one +can invoke ostree_sysroot_get_fd() after calling this function.

    +

    It is not necessary to call this function if ostree_sysroot_load() is +invoked.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    sysroot

     
    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_sysroot_initialize_with_mount_namespace ()

    +
    gboolean
    +ostree_sysroot_initialize_with_mount_namespace
    +                               (OstreeSysroot *self,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Prepare the current process for modifying a booted sysroot, if applicable. +This function subsumes the functionality of ostree_sysroot_initialize +and may be invoked wherever that function is.

    +

    If the sysroot does not appear to be booted, or where the current process is not uid 0, +this function returns successfully.

    +

    Otherwise, if the process is in the same mount namespace as pid 1, create +a new namespace.

    +

    If you invoke this function, it must be before ostree_sysroot_load(); it may +be invoked before or after ostree_sysroot_initialize().

    +

    Since: 2022.7

    +
    +
    +
    +

    ostree_sysroot_get_path ()

    +
    GFile *
    +ostree_sysroot_get_path (OstreeSysroot *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    Path to rootfs.

    +

    [transfer none][not nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_load ()

    +
    gboolean
    +ostree_sysroot_load (OstreeSysroot *self,
    +                     GCancellable *cancellable,
    +                     GError **error);
    +

    Load deployment list, bootversion, and subbootversion from the +rootfs self +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_load_if_changed ()

    +
    gboolean
    +ostree_sysroot_load_if_changed (OstreeSysroot *self,
    +                                gboolean *out_changed,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    OstreeSysroot

     

    out_changed

    .

    [out caller-allocates]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_sysroot_lock ()

    +
    gboolean
    +ostree_sysroot_lock (OstreeSysroot *self,
    +                     GError **error);
    +

    Acquire an exclusive multi-process write lock for self +. This call +blocks until the lock has been acquired. The lock is not +reentrant.

    +

    Release the lock with ostree_sysroot_unlock(). The lock will also +be released if self + is deallocated.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Self

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_try_lock ()

    +
    gboolean
    +ostree_sysroot_try_lock (OstreeSysroot *self,
    +                         gboolean *out_acquired,
    +                         GError **error);
    +

    Try to acquire an exclusive multi-process write lock for self +. If +another process holds the lock, this function will return +immediately, setting out_acquired + to FALSE, and returning TRUE +(and no error).

    +

    Release the lock with ostree_sysroot_unlock(). The lock will also +be released if self + is deallocated.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Self

     

    out_acquired

    Whether or not the lock has been acquired.

    [out]

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_lock_async ()

    +
    void
    +ostree_sysroot_lock_async (OstreeSysroot *self,
    +                           GCancellable *cancellable,
    +                           GAsyncReadyCallback callback,
    +                           gpointer user_data);
    +

    An asynchronous version of ostree_sysroot_lock().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    cancellable

    Cancellable

     

    callback

    Callback

     

    user_data

    User data

     
    +
    +
    +
    +
    +

    ostree_sysroot_lock_finish ()

    +
    gboolean
    +ostree_sysroot_lock_finish (OstreeSysroot *self,
    +                            GAsyncResult *result,
    +                            GError **error);
    +

    Call when ostree_sysroot_lock_async() is ready.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Self

     

    result

    Result

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_unlock ()

    +
    void
    +ostree_sysroot_unlock (OstreeSysroot *self);
    +

    Clear the lock previously acquired with ostree_sysroot_lock(). It +is safe to call this function if the lock has not been previously +acquired.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Self

     
    +
    +
    +
    +
    +

    ostree_sysroot_unload ()

    +
    void
    +ostree_sysroot_unload (OstreeSysroot *self);
    +

    Release any resources such as file descriptors referring to the +root directory of this sysroot. Normally, those resources are +cleared by finalization, but in garbage collected languages that +may not be predictable.

    +

    This undoes the effect of ostree_sysroot_load().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +
    +
    +

    ostree_sysroot_update_post_copy ()

    +
    gboolean
    +ostree_sysroot_update_post_copy (OstreeSysroot *self,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Update a sysroot as needed after having copied it into place using file-level +operations. This enables options like fs-verity on the required files that may +have been lost during the copy.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Sysroot

     

    error

    Error

     
    +
    +

    Since: 2023.11

    +
    +
    +
    +

    ostree_sysroot_set_mount_namespace_in_use ()

    +
    void
    +ostree_sysroot_set_mount_namespace_in_use
    +                               (OstreeSysroot *self);
    +

    If this function is invoked, then libostree will assume that +a private Linux mount namespace has been created by the process. +The primary use case for this is to have e.g. /sysroot mounted +read-only by default.

    +

    If this function has been called, then when a function which requires +writable access is invoked, libostree will automatically remount as writable +any mount points on which it operates. This currently is just /sysroot and +/boot.

    +

    If you invoke this function, it must be before ostree_sysroot_load(); it may +be invoked before or after ostree_sysroot_initialize().

    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_sysroot_is_booted ()

    +
    gboolean
    +ostree_sysroot_is_booted (OstreeSysroot *self);
    +

    Can only be invoked after ostree_sysroot_initialize().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    TRUE iff the sysroot points to a booted deployment

    +
    +

    Since: 2020.1

    +
    +
    +
    +

    ostree_sysroot_get_fd ()

    +
    int
    +ostree_sysroot_get_fd (OstreeSysroot *self);
    +

    Access a file descriptor that refers to the root directory of this sysroot. +ostree_sysroot_initialize() (or ostree_sysroot_load()) must have been invoked +prior to calling this function.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    A file descriptor valid for the lifetime of self +

    +
    +
    +
    +
    +

    ostree_sysroot_ensure_initialized ()

    +
    gboolean
    +ostree_sysroot_ensure_initialized (OstreeSysroot *self,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Ensure that self + is set up as a valid rootfs, by creating +/ostree/repo, among other things.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_get_bootversion ()

    +
    int
    +ostree_sysroot_get_bootversion (OstreeSysroot *self);
    +
    +
    +
    +

    ostree_sysroot_get_subbootversion ()

    +
    int
    +ostree_sysroot_get_subbootversion (OstreeSysroot *self);
    +
    +
    +
    +

    ostree_sysroot_get_deployments ()

    +
    GPtrArray *
    +ostree_sysroot_get_deployments (OstreeSysroot *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    Ordered list of deployments.

    +

    [element-type OstreeDeployment][transfer container]

    +
    +
    +
    +
    +

    ostree_sysroot_get_booted_deployment ()

    +
    OstreeDeployment *
    +ostree_sysroot_get_booted_deployment (OstreeSysroot *self);
    +

    This function may only be called if the sysroot is loaded.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    The currently booted deployment, or NULL if none.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_require_booted_deployment ()

    +
    OstreeDeployment *
    +ostree_sysroot_require_booted_deployment
    +                               (OstreeSysroot *self,
    +                                GError **error);
    +

    Find the booted deployment, or return an error if not booted via OSTree.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    The currently booted deployment, or an error.

    +

    [transfer none][not nullable]

    +
    +

    Since: 2021.1

    +
    +
    +
    +

    ostree_sysroot_get_deployment_directory ()

    +
    GFile *
    +ostree_sysroot_get_deployment_directory
    +                               (OstreeSysroot *self,
    +                                OstreeDeployment *deployment);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     
    +
    +
    +

    Returns

    +

    Path to deployment root directory.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_get_deployment_dirpath ()

    +
    char *
    +ostree_sysroot_get_deployment_dirpath (OstreeSysroot *self,
    +                                       OstreeDeployment *deployment);
    +

    Note this function only returns a *relative* path - if you want +to access, it, you must either use fd-relative api such as openat(), +or concatenate it with the full ostree_sysroot_get_path().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Repo

     

    deployment

    A deployment

     
    +
    +
    +

    Returns

    +

    Path to deployment root directory, relative to sysroot.

    +

    [transfer full][not nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_get_deployment_origin_path ()

    +
    GFile *
    +ostree_sysroot_get_deployment_origin_path
    +                               (GFile *deployment_path);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    deployment_path

    A deployment path

     
    +
    +
    +

    Returns

    +

    Path to deployment origin file.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_cleanup ()

    +
    gboolean
    +ostree_sysroot_cleanup (OstreeSysroot *self,
    +                        GCancellable *cancellable,
    +                        GError **error);
    +

    Delete any state that resulted from a partially completed +transaction, such as incomplete deployments.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_prepare_cleanup ()

    +
    gboolean
    +ostree_sysroot_prepare_cleanup (OstreeSysroot *self,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Like ostree_sysroot_cleanup() in that it cleans up incomplete deployments +and old boot versions, but does NOT prune the repository.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_cleanup_prune_repo ()

    +
    gboolean
    +ostree_sysroot_cleanup_prune_repo (OstreeSysroot *sysroot,
    +                                   OstreeRepoPruneOptions *options,
    +                                   gint *out_objects_total,
    +                                   gint *out_objects_pruned,
    +                                   guint64 *out_pruned_object_size_total,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Prune the system repository. This is a thin wrapper +around ostree_repo_prune_from_reachable(); the primary +addition is that this function automatically gathers +all deployed commits into the reachable set.

    +

    You generally want to at least set the OSTREE_REPO_PRUNE_FLAGS_REFS_ONLY +flag in options +. A commit traversal depth of 0 is assumed.

    +

    Locking: exclusive

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    sysroot

    Sysroot

     

    options

    Flags controlling pruning

     

    out_objects_total

    Number of objects found.

    [out]

    out_objects_pruned

    Number of objects deleted.

    [out]

    out_pruned_object_size_total

    Storage size in bytes of objects deleted.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_sysroot_repo ()

    +
    OstreeRepo *
    +ostree_sysroot_repo (OstreeSysroot *self);
    +

    This function is a variant of ostree_sysroot_get_repo() that cannot fail, and +returns a cached repository. Can only be called after ostree_sysroot_initialize() +or ostree_sysroot_load() has been invoked successfully.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    The OSTree repository in sysroot self +.

    +

    [transfer none][not nullable]

    +
    +

    Since: 2017.7

    +
    +
    +
    +

    ostree_sysroot_get_repo ()

    +
    gboolean
    +ostree_sysroot_get_repo (OstreeSysroot *self,
    +                         OstreeRepo **out_repo,
    +                         GCancellable *cancellable,
    +                         GError **error);
    +

    Retrieve the OSTree repository in sysroot self +. The repo is guaranteed to be open +(see ostree_repo_open()).

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    out_repo

    Repository in sysroot self +.

    [out][transfer full][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise

    +
    +
    +
    +
    +

    ostree_sysroot_get_staged_deployment ()

    +
    OstreeDeployment *
    +ostree_sysroot_get_staged_deployment (OstreeSysroot *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    The currently staged deployment, or NULL if none.

    +

    [transfer none][nullable]

    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_sysroot_init_osname ()

    +
    gboolean
    +ostree_sysroot_init_osname (OstreeSysroot *self,
    +                            const char *osname,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Initialize the directory structure for an "osname", which is a +group of operating system deployments, with a shared /var. One +is required for generating a deployment.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    Name group of operating system checkouts

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_sysroot_deployment_set_kargs ()

    +
    gboolean
    +ostree_sysroot_deployment_set_kargs (OstreeSysroot *self,
    +                                     OstreeDeployment *deployment,
    +                                     char **new_kargs,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Entirely replace the kernel arguments of deployment + with the +values in new_kargs +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     

    new_kargs

    Replace deployment's kernel arguments.

    [array zero-terminated=1][element-type utf8]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_deployment_set_kargs_in_place ()

    +
    gboolean
    +ostree_sysroot_deployment_set_kargs_in_place
    +                               (OstreeSysroot *self,
    +                                OstreeDeployment *deployment,
    +                                char *kargs_str,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Replace the kernel arguments of deployment + with the values in kargs_str +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     

    kargs_str

    Replace deployment +'s kernel arguments.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_deployment_set_mutable ()

    +
    gboolean
    +ostree_sysroot_deployment_set_mutable (OstreeSysroot *self,
    +                                       OstreeDeployment *deployment,
    +                                       gboolean is_mutable,
    +                                       GCancellable *cancellable,
    +                                       GError **error);
    +

    By default, deployment directories are not mutable. This function +will allow making them temporarily mutable, for example to allow +layering additional non-OSTree content.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     

    is_mutable

    Whether or not deployment's files can be changed

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_deployment_unlock ()

    +
    gboolean
    +ostree_sysroot_deployment_unlock (OstreeSysroot *self,
    +                                  OstreeDeployment *deployment,
    +                                  OstreeDeploymentUnlockedState unlocked_state,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Configure the target deployment deployment + such that it +is writable. There are multiple modes, essentially differing +in whether or not any changes persist across reboot.

    +

    The OSTREE_DEPLOYMENT_UNLOCKED_HOTFIX state is persistent +across reboots.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    Deployment

     

    unlocked_state

    Transition to this unlocked state

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_sysroot_deployment_set_pinned ()

    +
    gboolean
    +ostree_sysroot_deployment_set_pinned (OstreeSysroot *self,
    +                                      OstreeDeployment *deployment,
    +                                      gboolean is_pinned,
    +                                      GError **error);
    +

    By default, deployments may be subject to garbage collection. Typical uses of +libostree only retain at most 2 deployments. If is_pinned + is TRUE, a +metadata bit will be set causing libostree to avoid automatic GC of the +deployment. However, this is really an "advisory" note; it's still possible +for e.g. older versions of libostree unaware of pinning to GC the deployment.

    +

    This function does nothing and returns successfully if the deployment +is already in the desired pinning state. It is an error to try to pin +the staged deployment (as it's not in the bootloader entries).

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    A deployment

     

    is_pinned

    Whether or not deployment will be automatically GC'd

     

    error

    Error

     
    +
    +

    Since: 2018.3

    +
    +
    +
    +

    ostree_sysroot_write_deployments ()

    +
    gboolean
    +ostree_sysroot_write_deployments (OstreeSysroot *self,
    +                                  GPtrArray *new_deployments,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Older version of ostree_sysroot_write_deployments_with_options(). This +version will perform post-deployment cleanup by default.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    new_deployments

    List of new deployments.

    [element-type OstreeDeployment]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_write_deployments_with_options ()

    +
    gboolean
    +ostree_sysroot_write_deployments_with_options
    +                               (OstreeSysroot *self,
    +                                GPtrArray *new_deployments,
    +                                OstreeSysrootWriteDeploymentsOpts *opts,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Assuming new_deployments + have already been deployed in place on disk via +ostree_sysroot_deploy_tree(), atomically update bootloader configuration. By +default, no post-transaction cleanup will be performed. You should invoke +ostree_sysroot_cleanup() at some point after the transaction, or specify +do_postclean in opts +. Skipping the post-transaction cleanup is useful +if for example you want to control pruning of the repository.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    new_deployments

    List of new deployments.

    [element-type OstreeDeployment]

    opts

    Options

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2017.4

    +
    +
    +
    +

    ostree_sysroot_write_origin_file ()

    +
    gboolean
    +ostree_sysroot_write_origin_file (OstreeSysroot *sysroot,
    +                                  OstreeDeployment *deployment,
    +                                  GKeyFile *new_origin,
    +                                  GCancellable *cancellable,
    +                                  GError **error);
    +

    Immediately replace the origin file of the referenced deployment + +with the contents of new_origin +. If new_origin + is NULL, +this function will write the current origin of deployment +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    sysroot

    System root

     

    deployment

    Deployment

     

    new_origin

    Origin content.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_stage_tree ()

    +
    gboolean
    +ostree_sysroot_stage_tree (OstreeSysroot *self,
    +                           const char *osname,
    +                           const char *revision,
    +                           GKeyFile *origin,
    +                           OstreeDeployment *merge_deployment,
    +                           char **override_kernel_argv,
    +                           OstreeDeployment **out_new_deployment,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Older version of ostree_sysroot_stage_tree_with_options().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    osname to use for merge deployment.

    [allow-none]

    revision

    Checksum to add

     

    origin

    Origin to use for upgrades.

    [allow-none]

    merge_deployment

    Use this deployment for merge path.

    [allow-none]

    override_kernel_argv

    Use these as +kernel arguments; if NULL, inherit options from provided_merge_deployment.

    [allow-none][array zero-terminated=1][element-type utf8]

    out_new_deployment

    The new deployment path.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_sysroot_stage_tree_with_options ()

    +
    gboolean
    +ostree_sysroot_stage_tree_with_options
    +                               (OstreeSysroot *self,
    +                                const char *osname,
    +                                const char *revision,
    +                                GKeyFile *origin,
    +                                OstreeDeployment *merge_deployment,
    +                                OstreeSysrootDeployTreeOpts *opts,
    +                                OstreeDeployment **out_new_deployment,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Like ostree_sysroot_deploy_tree(), but "finalization" only occurs at OS +shutdown time.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    osname to use for merge deployment.

    [allow-none]

    revision

    Checksum to add

     

    origin

    Origin to use for upgrades.

    [allow-none]

    merge_deployment

    Use this deployment for merge path.

    [allow-none]

    opts

    Options

     

    out_new_deployment

    The new deployment path.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_sysroot_stage_overlay_initrd ()

    +
    gboolean
    +ostree_sysroot_stage_overlay_initrd (OstreeSysroot *self,
    +                                     int fd,
    +                                     char **out_checksum,
    +                                     GCancellable *cancellable,
    +                                     GError **error);
    +

    Stage an overlay initrd to be used in an upcoming deployment. Returns a checksum which +can be passed to ostree_sysroot_deploy_tree_with_options() or +ostree_sysroot_stage_tree_with_options() via the overlay_initrds array option.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    fd

    File descriptor to overlay initrd

     

    out_checksum

    Overlay initrd checksum.

    [out][transfer full]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_sysroot_change_finalization ()

    +
    gboolean
    +ostree_sysroot_change_finalization (OstreeSysroot *self,
    +                                    OstreeDeployment *deployment,
    +                                    GError **error);
    +

    Given the target deployment (which must be the staged deployment) this API +will toggle its "finalization locking" state. If it is currently locked, +it will be unlocked (and hence queued to apply on shutdown).

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    deployment

    Deployment which must be staged

     

    error

    Error

     
    +
    +

    Since: 2023.8

    +
    +
    +
    +

    ostree_sysroot_deploy_tree ()

    +
    gboolean
    +ostree_sysroot_deploy_tree (OstreeSysroot *self,
    +                            const char *osname,
    +                            const char *revision,
    +                            GKeyFile *origin,
    +                            OstreeDeployment *provided_merge_deployment,
    +                            char **override_kernel_argv,
    +                            OstreeDeployment **out_new_deployment,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Older version of ostree_sysroot_stage_tree_with_options().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    osname to use for merge deployment.

    [nullable]

    revision

    Checksum to add

     

    origin

    Origin to use for upgrades.

    [nullable]

    provided_merge_deployment

    Use this deployment for merge path.

    [nullable]

    override_kernel_argv

    Use these as +kernel arguments; if NULL, inherit options from provided_merge_deployment.

    [nullable][array zero-terminated=1][element-type utf8]

    out_new_deployment

    The new deployment path.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2018.5

    +
    +
    +
    +

    ostree_sysroot_deploy_tree_with_options ()

    +
    gboolean
    +ostree_sysroot_deploy_tree_with_options
    +                               (OstreeSysroot *self,
    +                                const char *osname,
    +                                const char *revision,
    +                                GKeyFile *origin,
    +                                OstreeDeployment *provided_merge_deployment,
    +                                OstreeSysrootDeployTreeOpts *opts,
    +                                OstreeDeployment **out_new_deployment,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Check out deployment tree with revision revision +, performing a 3 +way merge with provided_merge_deployment + for configuration.

    +

    When booted into the sysroot, you should use the +ostree_sysroot_stage_tree() API instead.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    osname to use for merge deployment.

    [nullable]

    revision

    Checksum to add

     

    origin

    Origin to use for upgrades.

    [nullable]

    provided_merge_deployment

    Use this deployment for merge path.

    [nullable]

    opts

    Options.

    [nullable]

    out_new_deployment

    The new deployment path.

    [out][transfer full]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_sysroot_get_merge_deployment ()

    +
    OstreeDeployment *
    +ostree_sysroot_get_merge_deployment (OstreeSysroot *self,
    +                                     const char *osname);
    +

    Find the deployment to use as a configuration merge source; this is +the first one in the current deployment list which matches osname.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    Operating system group.

    [allow-none]
    +
    +
    +

    Returns

    +

    Configuration merge deployment.

    +

    [transfer full][nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_query_deployments_for ()

    +
    void
    +ostree_sysroot_query_deployments_for (OstreeSysroot *self,
    +                                      const char *osname,
    +                                      OstreeDeployment **out_pending,
    +                                      OstreeDeployment **out_rollback);
    +

    Find the pending and rollback deployments for osname +. Pass NULL for osname + +to use the booted deployment's osname. By default, pending deployment is the +first deployment in the order that matches osname +, and rollback + will be the +next one after the booted deployment, or the deployment after the pending if +we're not looking at the booted deployment.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    osname

    "stateroot" name.

    [allow-none]

    out_pending

    The pending deployment.

    [out][nullable][optional][transfer full]

    out_rollback

    The rollback deployment.

    [out][nullable][optional][transfer full]
    +
    +

    Since: 2017.7

    +
    +
    +
    +

    ostree_sysroot_origin_new_from_refspec ()

    +
    GKeyFile *
    +ostree_sysroot_origin_new_from_refspec
    +                               (OstreeSysroot *self,
    +                                const char *refspec);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Sysroot

     

    refspec

    A refspec

     
    +
    +
    +

    Returns

    +

    A new config file which sets refspec +as an origin.

    +

    [transfer full][not nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_simple_write_deployment ()

    +
    gboolean
    +ostree_sysroot_simple_write_deployment
    +                               (OstreeSysroot *sysroot,
    +                                const char *osname,
    +                                OstreeDeployment *new_deployment,
    +                                OstreeDeployment *merge_deployment,
    +                                OstreeSysrootSimpleWriteDeploymentFlags flags,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Prepend new_deployment + to the list of deployments, commit, and +cleanup. By default, all other deployments for the given osname + +except the merge deployment and the booted deployment will be +garbage collected.

    +

    If OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN is +specified, then all current deployments will be kept.

    +

    If OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING is +specified, then pending deployments will be kept.

    +

    If OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK is +specified, then rollback deployments will be kept.

    +

    If OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT is +specified, then instead of prepending, the new deployment will be +added right after the booted or merge deployment, instead of first.

    +

    If OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN is +specified, then no cleanup will be performed after adding the +deployment. Make sure to call ostree_sysroot_cleanup() sometime +later, instead.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    sysroot

    Sysroot

     

    osname

    OS name.

    [allow-none]

    new_deployment

    Prepend this deployment to the list

     

    merge_deployment

    Use this deployment for configuration merge.

    [allow-none]

    flags

    Flags controlling behavior

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeSysroot

    +
    typedef struct OstreeSysroot OstreeSysroot;
    +
    +
    +
    +
    +

    enum OstreeSysrootSimpleWriteDeploymentFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE

      

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN

      

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NOT_DEFAULT

      

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NO_CLEAN

      

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_PENDING

      

    OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_RETAIN_ROLLBACK

      
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-SELinux-policy-management.html b/reference/ostree-SELinux-policy-management.html new file mode 100644 index 0000000000..116c2acf93 --- /dev/null +++ b/reference/ostree-SELinux-policy-management.html @@ -0,0 +1,566 @@ + + + + +SELinux policy management: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    SELinux policy management

    +

    SELinux policy management — Read SELinux policy and manage filesystem labels

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeSePolicy * + +ostree_sepolicy_new () +
    +OstreeSePolicy * + +ostree_sepolicy_new_at () +
    +OstreeSePolicy * + +ostree_sepolicy_new_from_commit () +
    +GFile * + +ostree_sepolicy_get_path () +
    const char * + +ostree_sepolicy_get_name () +
    +gboolean + +ostree_sepolicy_get_label () +
    const char * + +ostree_sepolicy_get_csum () +
    +gboolean + +ostree_sepolicy_restorecon () +
    +gboolean + +ostree_sepolicy_setfscreatecon () +
    +void + +ostree_sepolicy_fscreatecon_cleanup () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + +
    typedefOstreeSePolicy
    enumOstreeSePolicyRestoreconFlags
    +
    +
    +

    Description

    +

    A OstreeSePolicy object can load the SELinux policy from a given +root and perform labeling.

    +
    +
    +

    Functions

    +
    +

    ostree_sepolicy_new ()

    +
    OstreeSePolicy *
    +ostree_sepolicy_new (GFile *path,
    +                     GCancellable *cancellable,
    +                     GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    path

    Path to a root directory

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    An accessor object for SELinux policy in root located at path +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sepolicy_new_at ()

    +
    OstreeSePolicy *
    +ostree_sepolicy_new_at (int rootfs_dfd,
    +                        GCancellable *cancellable,
    +                        GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    rootfs_dfd

    Directory fd for rootfs (will not be cloned)

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    An accessor object for SELinux policy in root located at rootfs_dfd +.

    +

    [transfer full]

    +
    +

    Since: 2017.4

    +
    +
    +
    +

    ostree_sepolicy_new_from_commit ()

    +
    OstreeSePolicy *
    +ostree_sepolicy_new_from_commit (OstreeRepo *repo,
    +                                 const char *rev,
    +                                 GCancellable *cancellable,
    +                                 GError **error);
    +

    Extract the SELinux policy from a commit object via a partial checkout. This is useful +for labeling derived content as separate commits.

    +

    This function is the backend of ostree_repo_commit_modifier_set_sepolicy_from_commit().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    repo

    The repo

     

    rev

    ostree ref or checksum

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    A new policy.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sepolicy_get_path ()

    +
    GFile *
    +ostree_sepolicy_get_path (OstreeSePolicy *self);
    +

    This API should be considered deprecated, because it's supported for +policy objects to be created from file-descriptor relative paths, which +may not be globally accessible.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A SePolicy object

     
    +
    +
    +

    Returns

    +

    Path to rootfs.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_sepolicy_get_name ()

    +
    const char *
    +ostree_sepolicy_get_name (OstreeSePolicy *self);
    +
    +

    Returns

    +

    Type of current policy.

    +

    [transfer none]

    +
    +
    +
    +
    +

    ostree_sepolicy_get_label ()

    +
    gboolean
    +ostree_sepolicy_get_label (OstreeSePolicy *self,
    +                           const char *relpath,
    +                           guint32 unix_mode,
    +                           char **out_label,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Store in out_label + the security context for the given relpath + and +mode unix_mode +. If the policy does not specify a label, NULL +will be returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    relpath

    Path

     

    unix_mode

    Unix mode

     

    out_label

    Return location for security context.

    [nullable][out][transfer full]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sepolicy_get_csum ()

    +
    const char *
    +ostree_sepolicy_get_csum (OstreeSePolicy *self);
    +
    +

    Returns

    +

    Checksum of current policy.

    +

    [transfer none][nullable]

    +
    +

    Since: 2016.5

    +
    +
    +
    +

    ostree_sepolicy_restorecon ()

    +
    gboolean
    +ostree_sepolicy_restorecon (OstreeSePolicy *self,
    +                            const char *path,
    +                            GFileInfo *info,
    +                            GFile *target,
    +                            OstreeSePolicyRestoreconFlags flags,
    +                            char **out_new_label,
    +                            GCancellable *cancellable,
    +                            GError **error);
    +

    Reset the security context of target + based on the SELinux policy.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    path

    Path string to use for policy lookup

     

    info

    File attributes.

    [nullable]

    target

    Physical path to target file

     

    flags

    Flags controlling behavior

     

    out_new_label

    New label, or NULL if unchanged.

    [nullable][optional][out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sepolicy_setfscreatecon ()

    +
    gboolean
    +ostree_sepolicy_setfscreatecon (OstreeSePolicy *self,
    +                                const char *path,
    +                                guint32 mode,
    +                                GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Policy

     

    path

    Use this path to determine a label

     

    mode

    Used along with path +

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sepolicy_fscreatecon_cleanup ()

    +
    void
    +ostree_sepolicy_fscreatecon_cleanup (void **unused);
    +

    Cleanup function for ostree_sepolicy_setfscreatecon().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    unused

    Not used, just in case you didn't infer that from the parameter name

     
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeSePolicy

    +
    typedef struct OstreeSePolicy OstreeSePolicy;
    +
    +
    +
    +
    +

    enum OstreeSePolicyRestoreconFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + +

    OSTREE_SEPOLICY_RESTORECON_FLAGS_NONE

      

    OSTREE_SEPOLICY_RESTORECON_FLAGS_ALLOW_NOLABEL

      

    OSTREE_SEPOLICY_RESTORECON_FLAGS_KEEP_EXISTING

      
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-Signature-management.html b/reference/ostree-Signature-management.html new file mode 100644 index 0000000000..3ac4fce308 --- /dev/null +++ b/reference/ostree-Signature-management.html @@ -0,0 +1,878 @@ + + + + +Signature management: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Signature management

    +

    Signature management — Sign and verify commits

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +GPtrArray * + +ostree_sign_get_all () +
    +gboolean + +ostree_sign_commit () +
    +gboolean + +ostree_sign_commit_verify () +
    +gboolean + +ostree_sign_data () +
    +gboolean + +ostree_sign_data_verify () +
    +OstreeSign * + +ostree_sign_get_by_name () +
    const gchar * + +ostree_sign_get_name () +
    +gboolean + +ostree_sign_add_pk () +
    +gboolean + +ostree_sign_clear_keys () +
    +gboolean + +ostree_sign_load_pk () +
    const gchar * + +ostree_sign_metadata_format () +
    const gchar * + +ostree_sign_metadata_key () +
    +gboolean + +ostree_sign_set_pk () +
    +gboolean + +ostree_sign_set_sk () +
    +gboolean + +ostree_sign_summary () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
     OstreeSign
    +
    +
    +

    Description

    +

    An OstreeSign interface allows to select and use any available engine +for signing or verifying the commit object or summary file.

    +
    +
    +

    Functions

    +
    +

    ostree_sign_get_all ()

    +
    GPtrArray *
    +ostree_sign_get_all (void);
    +

    Return an array with newly allocated instances of all available +signing engines; they will not be initialized.

    +
    +

    Returns

    +

    an array of signing engines.

    +

    [transfer full][element-type OstreeSign]

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_commit ()

    +
    gboolean
    +ostree_sign_commit (OstreeSign *self,
    +                    OstreeRepo *repo,
    +                    const gchar *commit_checksum,
    +                    GCancellable *cancellable,
    +                    GError **error);
    +

    Add a signature to a commit.

    +

    Depending of the signing engine used you will need to load +the secret key with ostree_sign_set_sk.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    repo

    an OsreeRepo object

     

    commit_checksum

    SHA256 of given commit to sign

     

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +if commit has been signed successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_commit_verify ()

    +
    gboolean
    +ostree_sign_commit_verify (OstreeSign *self,
    +                           OstreeRepo *repo,
    +                           const gchar *commit_checksum,
    +                           char **out_success_message,
    +                           GCancellable *cancellable,
    +                           GError **error);
    +

    Verify if commit is signed with known key.

    +

    Depending of the signing engine used you will need to load +the public key(s) for verification with ostree_sign_set_pk, +ostree_sign_add_pk and/or ostree_sign_load_pk.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    repo

    an OsreeRepo object

     

    commit_checksum

    SHA256 of given commit to verify

     

    out_success_message

    success message returned by the signing +engine.

    [out][nullable][optional]

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +if commit has been verified successfully, +FALSE +in case of error or no valid keys are available (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_data ()

    +
    gboolean
    +ostree_sign_data (OstreeSign *self,
    +                  GBytes *data,
    +                  GBytes **signature,
    +                  GCancellable *cancellable,
    +                  GError **error);
    +

    Sign the given data + with pre-loaded secret key.

    +

    Depending of the signing engine used you will need to load +the secret key with ostree_sign_set_sk.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    data

    the raw data to be signed with pre-loaded secret key

     

    signature

    in case of success will contain signature.

    [out]

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +if data +has been signed successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_data_verify ()

    +
    gboolean
    +ostree_sign_data_verify (OstreeSign *self,
    +                         GBytes *data,
    +                         GVariant *signatures,
    +                         char **out_success_message,
    +                         GError **error);
    +

    Verify given data against signatures with pre-loaded public keys.

    +

    Depending of the signing engine used you will need to load +the public key(s) with ostree_sign_set_pk, ostree_sign_add_pk +or ostree_sign_load_pk.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    data

    the raw data to check

     

    signatures

    the signatures to be checked

     

    out_success_message

    success message returned by the signing +engine.

    [out][nullable][optional]

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +if data +has been signed at least with any single valid key, +FALSE +in case of error or no valid keys are available (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_get_by_name ()

    +
    OstreeSign *
    +ostree_sign_get_by_name (const gchar *name,
    +                         GError **error);
    +

    Create a new instance of a signing engine.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    name

    the name of desired signature engine

     

    error

    return location for a GError

     
    +
    +
    +

    Returns

    +

    New signing engine, or NULL if the engine is not known.

    +

    [transfer full]

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_get_name ()

    +
    const gchar *
    +ostree_sign_get_name (OstreeSign *self);
    +

    Return the pointer to the name of currently used/selected signing engine.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeSign object

     
    +
    +
    +

    Returns

    +

    pointer to the name +NULL +in case of error (unlikely).

    +

    [transfer none]

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_add_pk ()

    +
    gboolean
    +ostree_sign_add_pk (OstreeSign *self,
    +                    GVariant *public_key,
    +                    GError **error);
    +

    Add the public key for verification. Could be called multiple times for +adding all needed keys to be used for verification.

    +

    The public_key + argument depends of the particular engine implementation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    public_key

    single public key to be added

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +in case if the key could be added successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_clear_keys ()

    +
    gboolean
    +ostree_sign_clear_keys (OstreeSign *self,
    +                        GError **error);
    +

    Clear all previously preloaded secret and public keys.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +in case if no errors, FALSE +in case of error

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_load_pk ()

    +
    gboolean
    +ostree_sign_load_pk (OstreeSign *self,
    +                     GVariant *options,
    +                     GError **error);
    +

    Load public keys for verification from anywhere. +It is expected that all keys would be added to already pre-loaded keys.

    +

    The options + argument depends of the particular engine implementation.

    +

    For example, ed25515 + engine could use following string-formatted options:

    +
      +
    • filename + -- single file to use to load keys from

    • +
    • basedir + -- directory containing subdirectories +'trusted.ed25519.d' and 'revoked.ed25519.d' with appropriate +public keys. Used for testing and re-definition of system-wide +directories if defaults are not suitable for any reason.

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    options

    any options

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +in case if at least one key could be load successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_metadata_format ()

    +
    const gchar *
    +ostree_sign_metadata_format (OstreeSign *self);
    +

    Return the pointer to the string with format used in (detached) metadata for +current signing engine.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeSign object

     
    +
    +
    +

    Returns

    +

    pointer to the metadata format, +NULL +in case of error (unlikely).

    +

    [transfer none]

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_metadata_key ()

    +
    const gchar *
    +ostree_sign_metadata_key (OstreeSign *self);
    +

    Return the pointer to the name of the key used in (detached) metadata for +current signing engine.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    an OstreeSign object

     
    +
    +
    +

    Returns

    +

    pointer to the metadata key name, +NULL +in case of error (unlikely).

    +

    [transfer none]

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_set_pk ()

    +
    gboolean
    +ostree_sign_set_pk (OstreeSign *self,
    +                    GVariant *public_key,
    +                    GError **error);
    +

    Set the public key for verification. It is expected what all +previously pre-loaded public keys will be dropped.

    +

    The public_key + argument depends of the particular engine implementation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    public_key

    single public key to be added

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +in case if the key could be set successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_set_sk ()

    +
    gboolean
    +ostree_sign_set_sk (OstreeSign *self,
    +                    GVariant *secret_key,
    +                    GError **error);
    +

    Set the secret key to be used for signing data, commits and summary.

    +

    The secret_key + argument depends of the particular engine implementation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeSign object

     

    secret_key

    secret key to be added

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +in case if the key could be set successfully, +FALSE +in case of error (error +will contain the reason).

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    ostree_sign_summary ()

    +
    gboolean
    +ostree_sign_summary (OstreeSign *self,
    +                     OstreeRepo *repo,
    +                     GVariant *keys,
    +                     GCancellable *cancellable,
    +                     GError **error);
    +

    Add a signature to a summary file. +Based on ostree_repo_add_gpg_signature_summary implementation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Self

     

    repo

    ostree repository

     

    keys

    keys -- GVariant containing keys as GVarints specific to signature type.

     

    cancellable

    A GCancellable

     

    error

    a GError

     
    +
    +
    +

    Returns

    +

    TRUE +if summary file has been signed with all provided keys

    +
    +

    Since: 2020.2

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeSign

    +
    typedef struct _OstreeSign OstreeSign;
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-Simple-upgrade-class.html b/reference/ostree-Simple-upgrade-class.html new file mode 100644 index 0000000000..346ffd4023 --- /dev/null +++ b/reference/ostree-Simple-upgrade-class.html @@ -0,0 +1,726 @@ + + + + +Simple upgrade class: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    Simple upgrade class

    +

    Simple upgrade class — Upgrade OSTree systems

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeSysrootUpgrader * + +ostree_sysroot_upgrader_new () +
    +OstreeSysrootUpgrader * + +ostree_sysroot_upgrader_new_for_os () +
    +OstreeSysrootUpgrader * + +ostree_sysroot_upgrader_new_for_os_with_flags () +
    +GKeyFile * + +ostree_sysroot_upgrader_get_origin () +
    +GKeyFile * + +ostree_sysroot_upgrader_dup_origin () +
    +gboolean + +ostree_sysroot_upgrader_set_origin () +
    +char * + +ostree_sysroot_upgrader_get_origin_description () +
    +gboolean + +ostree_sysroot_upgrader_check_timestamps () +
    +gboolean + +ostree_sysroot_upgrader_pull () +
    +gboolean + +ostree_sysroot_upgrader_pull_one_dir () +
    +gboolean + +ostree_sysroot_upgrader_deploy () +
    +
    +
    +

    Types and Values

    + +
    +
    +

    Description

    +

    The OstreeSysrootUpgrader class allows performing simple upgrade +operations.

    +
    +
    +

    Functions

    +
    +

    ostree_sysroot_upgrader_new ()

    +
    OstreeSysrootUpgrader *
    +ostree_sysroot_upgrader_new (OstreeSysroot *sysroot,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    sysroot

    An OstreeSysroot

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    An upgrader.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_new_for_os ()

    +
    OstreeSysrootUpgrader *
    +ostree_sysroot_upgrader_new_for_os (OstreeSysroot *sysroot,
    +                                    const char *osname,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    sysroot

    An OstreeSysroot

     

    osname

    Operating system name.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    An upgrader.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_new_for_os_with_flags ()

    +
    OstreeSysrootUpgrader *
    +ostree_sysroot_upgrader_new_for_os_with_flags
    +                               (OstreeSysroot *sysroot,
    +                                const char *osname,
    +                                OstreeSysrootUpgraderFlags flags,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    sysroot

    An OstreeSysroot

     

    osname

    Operating system name.

    [allow-none]

    flags

    Flags

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    An upgrader.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_get_origin ()

    +
    GKeyFile *
    +ostree_sysroot_upgrader_get_origin (OstreeSysrootUpgrader *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    The origin file, or NULL if unknown.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_dup_origin ()

    +
    GKeyFile *
    +ostree_sysroot_upgrader_dup_origin (OstreeSysrootUpgrader *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Sysroot

     
    +
    +
    +

    Returns

    +

    A copy of the origin file, or NULL if unknown.

    +

    [transfer full][nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_set_origin ()

    +
    gboolean
    +ostree_sysroot_upgrader_set_origin (OstreeSysrootUpgrader *self,
    +                                    GKeyFile *origin,
    +                                    GCancellable *cancellable,
    +                                    GError **error);
    +

    Replace the origin with origin +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    Sysroot

     

    origin

    The new origin.

    [allow-none]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_get_origin_description ()

    +
    char *
    +ostree_sysroot_upgrader_get_origin_description
    +                               (OstreeSysrootUpgrader *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Upgrader

     
    +
    +
    +

    Returns

    +

    A one-line descriptive summary of the origin, or NULL if +unknown.

    +

    [transfer full][nullable]

    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_check_timestamps ()

    +
    gboolean
    +ostree_sysroot_upgrader_check_timestamps
    +                               (OstreeRepo *repo,
    +                                const char *from_rev,
    +                                const char *to_rev,
    +                                GError **error);
    +

    Check that the timestamp on to_rev + is equal to or newer than +from_rev +. This protects systems against man-in-the-middle +attackers which provide a client with an older commit.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    repo

    Repo

     

    from_rev

    From revision

     

    to_rev

    To revision

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_pull ()

    +
    gboolean
    +ostree_sysroot_upgrader_pull (OstreeSysrootUpgrader *self,
    +                              OstreeRepoPullFlags flags,
    +                              OstreeSysrootUpgraderPullFlags upgrader_flags,
    +                              OstreeAsyncProgress *progress,
    +                              gboolean *out_changed,
    +                              GCancellable *cancellable,
    +                              GError **error);
    +

    Perform a pull from the origin. First check if the ref has +changed, if so download the linked objects, and store the updated +ref locally. Then out_changed + will be TRUE.

    +

    If the origin remote is unchanged, out_changed + will be set to +FALSE.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Upgrader

     

    flags

    Flags controlling pull behavior

     

    upgrader_flags

    Flags controlling upgrader behavior

     

    progress

    Progress.

    [allow-none]

    out_changed

    Whether or not the origin changed.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_pull_one_dir ()

    +
    gboolean
    +ostree_sysroot_upgrader_pull_one_dir (OstreeSysrootUpgrader *self,
    +                                      const char *dir_to_pull,
    +                                      OstreeRepoPullFlags flags,
    +                                      OstreeSysrootUpgraderPullFlags upgrader_flags,
    +                                      OstreeAsyncProgress *progress,
    +                                      gboolean *out_changed,
    +                                      GCancellable *cancellable,
    +                                      GError **error);
    +

    Like ostree_sysroot_upgrader_pull(), but allows retrieving just a +subpath of the tree. This can be used to download metadata files +from inside the tree such as package databases.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Upgrader

     

    dir_to_pull

    Subdirectory path (should include a leading /)

     

    flags

    Flags controlling pull behavior

     

    upgrader_flags

    Flags controlling upgrader behavior

     

    progress

    Progress.

    [allow-none]

    out_changed

    Whether or not the origin changed.

    [out]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_sysroot_upgrader_deploy ()

    +
    gboolean
    +ostree_sysroot_upgrader_deploy (OstreeSysrootUpgrader *self,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Write the new deployment to disk, perform a configuration merge +with /etc, and update the bootloader configuration.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Self

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeSysrootUpgrader

    +
    typedef struct OstreeSysrootUpgrader OstreeSysrootUpgrader;
    +
    +
    +
    +
    +

    enum OstreeSysrootUpgraderFlags

    +

    Flags controlling operation of an OstreeSysrootUpgrader.

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + +

    OSTREE_SYSROOT_UPGRADER_FLAGS_NONE

    +

    No options

    +
     

    OSTREE_SYSROOT_UPGRADER_FLAGS_IGNORE_UNCONFIGURED

    +

    Do not error if the origin has an +unconfigured-state key

    +
     

    OSTREE_SYSROOT_UPGRADER_FLAGS_STAGE

    +

    Enable "staging" (finalization at shutdown); recommended +(Since: 2021.4)

    +
     
    +
    +
    +
    +
    +

    enum OstreeSysrootUpgraderPullFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + +

    OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_NONE

      

    OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_ALLOW_OLDER

      

    OSTREE_SYSROOT_UPGRADER_PULL_FLAGS_SYNTHETIC

      
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-bootconfig-parser.html b/reference/ostree-ostree-bootconfig-parser.html new file mode 100644 index 0000000000..9cda254801 --- /dev/null +++ b/reference/ostree-ostree-bootconfig-parser.html @@ -0,0 +1,400 @@ + + + + +ostree-bootconfig-parser: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-bootconfig-parser

    +

    ostree-bootconfig-parser

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeBootconfigParser * + +ostree_bootconfig_parser_new () +
    +OstreeBootconfigParser * + +ostree_bootconfig_parser_clone () +
    +gboolean + +ostree_bootconfig_parser_parse () +
    +gboolean + +ostree_bootconfig_parser_parse_at () +
    +gboolean + +ostree_bootconfig_parser_write () +
    +gboolean + +ostree_bootconfig_parser_write_at () +
    +void + +ostree_bootconfig_parser_set () +
    const char * + +ostree_bootconfig_parser_get () +
    +void + +ostree_bootconfig_parser_set_overlay_initrds () +
    +char ** + +ostree_bootconfig_parser_get_overlay_initrds () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
     OstreeBootconfigParser
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_bootconfig_parser_new ()

    +
    OstreeBootconfigParser *
    +ostree_bootconfig_parser_new (void);
    +
    +
    +
    +

    ostree_bootconfig_parser_clone ()

    +
    OstreeBootconfigParser *
    +ostree_bootconfig_parser_clone (OstreeBootconfigParser *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Bootconfig to clone

     
    +
    +
    +

    Returns

    +

    Copy of self +.

    +

    [transfer full]

    +
    +
    +
    +
    +

    ostree_bootconfig_parser_parse ()

    +
    gboolean
    +ostree_bootconfig_parser_parse (OstreeBootconfigParser *self,
    +                                GFile *path,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +
    +
    +
    +

    ostree_bootconfig_parser_parse_at ()

    +
    gboolean
    +ostree_bootconfig_parser_parse_at (OstreeBootconfigParser *self,
    +                                   int dfd,
    +                                   const char *path,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +

    Initialize a bootconfig from the given file.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    Parser

     

    dfd

    Directory fd

     

    path

    File path

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_bootconfig_parser_write ()

    +
    gboolean
    +ostree_bootconfig_parser_write (OstreeBootconfigParser *self,
    +                                GFile *output,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +
    +
    +
    +

    ostree_bootconfig_parser_write_at ()

    +
    gboolean
    +ostree_bootconfig_parser_write_at (OstreeBootconfigParser *self,
    +                                   int dfd,
    +                                   const char *path,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +
    +
    +
    +

    ostree_bootconfig_parser_set ()

    +
    void
    +ostree_bootconfig_parser_set (OstreeBootconfigParser *self,
    +                              const char *key,
    +                              const char *value);
    +

    Set the key +/value + pair to the boot configuration dictionary.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Parser

     

    key

    the key

     

    value

    the key

     
    +
    +
    +
    +
    +

    ostree_bootconfig_parser_get ()

    +
    const char *
    +ostree_bootconfig_parser_get (OstreeBootconfigParser *self,
    +                              const char *key);
    +

    Get the value corresponding to key + from the boot configuration dictionary.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Parser

     

    key

    the key name to retrieve

     
    +
    +
    +

    Returns

    +

    The corresponding value, or NULL if the key hasn't been +found.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_bootconfig_parser_set_overlay_initrds ()

    +
    void
    +ostree_bootconfig_parser_set_overlay_initrds
    +                               (OstreeBootconfigParser *self,
    +                                char **initrds);
    +

    These are rendered as additional initrd keys in the final bootloader configs. The +base initrd is part of the primary keys.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Parser

     

    initrds

    Array of overlay +initrds or NULL to unset.

    [array zero-terminated=1][transfer none][allow-none]
    +
    +

    Since: 2020.7

    +
    +
    +
    +

    ostree_bootconfig_parser_get_overlay_initrds ()

    +
    char **
    +ostree_bootconfig_parser_get_overlay_initrds
    +                               (OstreeBootconfigParser *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Parser

     
    +
    +
    +

    Returns

    +

    Array of initrds or NULL +if none are set.

    +

    [array zero-terminated=1][transfer none][nullable]

    +
    +

    Since: 2020.7

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeBootconfigParser

    +
    typedef struct _OstreeBootconfigParser OstreeBootconfigParser;
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-chain-input-stream.html b/reference/ostree-ostree-chain-input-stream.html new file mode 100644 index 0000000000..8f5262a3ac --- /dev/null +++ b/reference/ostree-ostree-chain-input-stream.html @@ -0,0 +1,89 @@ + + + + +ostree-chain-input-stream: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-chain-input-stream

    +

    ostree-chain-input-stream

    +
    +
    +

    Functions

    + +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    structOstreeChainInputStream
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_chain_input_stream_new ()

    +
    OstreeChainInputStream *
    +ostree_chain_input_stream_new (GPtrArray *streams);
    +
    +
    +
    +

    Types and Values

    +
    +

    struct OstreeChainInputStream

    +
    struct OstreeChainInputStream {
    +  GInputStream parent_instance;
    +};
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-checksum-input-stream.html b/reference/ostree-ostree-checksum-input-stream.html new file mode 100644 index 0000000000..72e2a30d38 --- /dev/null +++ b/reference/ostree-ostree-checksum-input-stream.html @@ -0,0 +1,90 @@ + + + + +ostree-checksum-input-stream: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-checksum-input-stream

    +

    ostree-checksum-input-stream

    +
    +
    +

    Functions

    + +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    structOstreeChecksumInputStream
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_checksum_input_stream_new ()

    +
    OstreeChecksumInputStream *
    +ostree_checksum_input_stream_new (GInputStream *stream,
    +                                  GChecksum *checksum);
    +
    +
    +
    +

    Types and Values

    +
    +

    struct OstreeChecksumInputStream

    +
    struct OstreeChecksumInputStream {
    +  GFilterInputStream parent_instance;
    +};
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-content-writer.html b/reference/ostree-ostree-content-writer.html new file mode 100644 index 0000000000..406f81dc3d --- /dev/null +++ b/reference/ostree-ostree-content-writer.html @@ -0,0 +1,101 @@ + + + + +ostree-content-writer: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-content-writer

    +

    ostree-content-writer

    +
    +
    +

    Functions

    +
    ++++ + + + + +
    +char * + +ostree_content_writer_finish () +
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_content_writer_finish ()

    +
    char *
    +ostree_content_writer_finish (OstreeContentWriter *self,
    +                              GCancellable *cancellable,
    +                              GError **error);
    +

    Complete the object write and return the checksum.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    Writer

     

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    Checksum, or NULL on error.

    +

    [transfer full]

    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-deployment.html b/reference/ostree-ostree-deployment.html new file mode 100644 index 0000000000..4ef84dce5b --- /dev/null +++ b/reference/ostree-ostree-deployment.html @@ -0,0 +1,884 @@ + + + + +ostree-deployment: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-deployment

    +

    ostree-deployment

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +guint + +ostree_deployment_hash () +
    +gboolean + +ostree_deployment_equal () +
    +OstreeDeployment * + +ostree_deployment_new () +
    +int + +ostree_deployment_get_index () +
    const char * + +ostree_deployment_get_osname () +
    +int + +ostree_deployment_get_deployserial () +
    const char * + +ostree_deployment_get_csum () +
    const char * + +ostree_deployment_get_bootcsum () +
    +int + +ostree_deployment_get_bootserial () +
    +OstreeBootconfigParser * + +ostree_deployment_get_bootconfig () +
    +GKeyFile * + +ostree_deployment_get_origin () +
    +char * + +ostree_deployment_get_origin_relpath () +
    +OstreeDeploymentUnlockedState + +ostree_deployment_get_unlocked () +
    +gboolean + +ostree_deployment_is_pinned () +
    +gboolean + +ostree_deployment_is_staged () +
    +gboolean + +ostree_deployment_is_finalization_locked () +
    +void + +ostree_deployment_set_index () +
    +void + +ostree_deployment_set_bootserial () +
    +void + +ostree_deployment_set_bootconfig () +
    +void + +ostree_deployment_set_origin () +
    +void + +ostree_deployment_origin_remove_transient_state () +
    +OstreeDeployment * + +ostree_deployment_clone () +
    const char * + +ostree_deployment_unlocked_state_to_string () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
     OstreeDeployment
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_deployment_hash ()

    +
    guint
    +ostree_deployment_hash (gconstpointer v);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    v

    Deployment.

    [type OstreeDeployment]
    +
    +
    +

    Returns

    +

    An integer suitable for use in a GHashTable

    +
    +
    +
    +
    +

    ostree_deployment_equal ()

    +
    gboolean
    +ostree_deployment_equal (gconstpointer ap,
    +                         gconstpointer bp);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    ap

    A deployment.

    [type OstreeDeployment]

    bp

    A deployment.

    [type OstreeDeployment]
    +
    +
    +

    Returns

    +

    TRUE if deployments have the same osname, csum, and deployserial

    +
    +
    +
    +
    +

    ostree_deployment_new ()

    +
    OstreeDeployment *
    +ostree_deployment_new (int index,
    +                       const char *osname,
    +                       const char *csum,
    +                       int deployserial,
    +                       const char *bootcsum,
    +                       int bootserial);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    index

    Global index into the bootloader entries

     

    osname

    "stateroot" for this deployment

     

    csum

    OSTree commit that will be deployed

     

    deployserial

    Unique counter

     

    bootcsum

    Kernel/initrd checksum.

    [nullable]

    bootserial

    Unique index

     
    +
    +
    +

    Returns

    +

    New deployment.

    +

    [transfer full][not nullable]

    +
    +
    +
    +
    +

    ostree_deployment_get_index ()

    +
    int
    +ostree_deployment_get_index (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    The global index into the bootloader ordering

    +
    +
    +
    +
    +

    ostree_deployment_get_osname ()

    +
    const char *
    +ostree_deployment_get_osname (OstreeDeployment *self);
    +
    +
    +
    +

    ostree_deployment_get_deployserial ()

    +
    int
    +ostree_deployment_get_deployserial (OstreeDeployment *self);
    +
    +
    +
    +

    ostree_deployment_get_csum ()

    +
    const char *
    +ostree_deployment_get_csum (OstreeDeployment *self);
    +
    +
    +
    +

    ostree_deployment_get_bootcsum ()

    +
    const char *
    +ostree_deployment_get_bootcsum (OstreeDeployment *self);
    +
    +
    +
    +

    ostree_deployment_get_bootserial ()

    +
    int
    +ostree_deployment_get_bootserial (OstreeDeployment *self);
    +
    +
    +
    +

    ostree_deployment_get_bootconfig ()

    +
    OstreeBootconfigParser *
    +ostree_deployment_get_bootconfig (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    Boot configuration.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_deployment_get_origin ()

    +
    GKeyFile *
    +ostree_deployment_get_origin (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    Origin.

    +

    [transfer none][nullable]

    +
    +
    +
    +
    +

    ostree_deployment_get_origin_relpath ()

    +
    char *
    +ostree_deployment_get_origin_relpath (OstreeDeployment *self);
    +

    Note this function only returns a *relative* path - if you want to +access, it, you must either use fd-relative api such as openat(), +or concatenate it with the full ostree_sysroot_get_path().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A deployment

     
    +
    +
    +

    Returns

    +

    Path to deployment root directory, relative to sysroot.

    +

    [not nullable][transfer full]

    +
    +
    +
    +
    +

    ostree_deployment_get_unlocked ()

    +
    OstreeDeploymentUnlockedState
    +ostree_deployment_get_unlocked (OstreeDeployment *self);
    +

    Since: 2016.4

    +
    +
    +
    +

    ostree_deployment_is_pinned ()

    +
    gboolean
    +ostree_deployment_is_pinned (OstreeDeployment *self);
    +

    See ostree_sysroot_deployment_set_pinned().

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    TRUE if deployment will not be subject to GC

    +
    +

    Since: 2018.3

    +
    +
    +
    +

    ostree_deployment_is_staged ()

    +
    gboolean
    +ostree_deployment_is_staged (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    TRUE if deployment should be "finalized" at shutdown time

    +
    +

    Since: 2018.3

    +
    +
    +
    +

    ostree_deployment_is_finalization_locked ()

    +
    gboolean
    +ostree_deployment_is_finalization_locked
    +                               (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    TRUE if deployment is queued to be "finalized" at shutdown time, but requires +additional action.

    +
    +

    Since: 2023.8

    +
    +
    +
    +

    ostree_deployment_set_index ()

    +
    void
    +ostree_deployment_set_index (OstreeDeployment *self,
    +                             int index);
    +

    Sets the global index into the bootloader ordering.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Deployment

     

    index

    Index into bootloader ordering

     
    +
    +
    +
    +
    +

    ostree_deployment_set_bootserial ()

    +
    void
    +ostree_deployment_set_bootserial (OstreeDeployment *self,
    +                                  int index);
    +

    Should never have been made public API; don't use this.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Deployment

     

    index

    Don't use this

     
    +
    +
    +
    +
    +

    ostree_deployment_set_bootconfig ()

    +
    void
    +ostree_deployment_set_bootconfig (OstreeDeployment *self,
    +                                  OstreeBootconfigParser *bootconfig);
    +

    Set or clear the bootloader configuration.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Deployment

     

    bootconfig

    Bootloader configuration object.

    [nullable]
    +
    +
    +
    +
    +

    ostree_deployment_set_origin ()

    +
    void
    +ostree_deployment_set_origin (OstreeDeployment *self,
    +                              GKeyFile *origin);
    +

    Replace the "origin", which is a description of the source +of the deployment and how to update to the next version.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    Deployment

     

    origin

    Set the origin for this deployment.

    [nullable]
    +
    +
    +
    +
    +

    ostree_deployment_origin_remove_transient_state ()

    +
    void
    +ostree_deployment_origin_remove_transient_state
    +                               (GKeyFile *origin);
    +

    The intention of an origin file is primarily describe the "inputs" that +resulted in a deployment, and it's commonly used to derive the new state. For +example, a key value (in pure libostree mode) is the "refspec". However, +libostree (or other applications) may want to store "transient" state that +should not be carried across upgrades.

    +

    This function just removes all members of the libostree-transient group. +The name of that group is available to all libostree users; best practice +would be to prefix values underneath there with a short identifier for your +software.

    +

    Additionally, this function will remove the origin/unlocked and +origin/override-commit members; these should be considered transient state +that should have been under an explicit group.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    origin

    An origin

     
    +
    +

    Since: 2018.3

    +
    +
    +
    +

    ostree_deployment_clone ()

    +
    OstreeDeployment *
    +ostree_deployment_clone (OstreeDeployment *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    Deployment

     
    +
    +
    +

    Returns

    +

    New deep copy of self +.

    +

    [not nullable][transfer full]

    +
    +
    +
    +
    +

    ostree_deployment_unlocked_state_to_string ()

    +
    const char *
    +ostree_deployment_unlocked_state_to_string
    +                               (OstreeDeploymentUnlockedState state);
    +
    +

    Returns

    +

    Description of state.

    +

    [not nullable]

    +
    +

    Since: 2016.4

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeDeployment

    +
    typedef struct {
    +  GObject parent_instance;
    +
    +  int index;
    +  char *osname;
    +  char *csum;
    +  int deployserial;
    +  char *bootcsum;
    +  int bootserial;
    +  OstreeBootconfigParser *bootconfig;
    +  GKeyFile *origin;
    +  OstreeDeploymentUnlockedState unlocked;
    +  gboolean staged;
    +  gboolean finalization_locked;
    +  char **overlay_initrds;
    +  char *overlay_initrds_id;
    +} OstreeDeployment;
    +
    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    int index;

    Global offset

     

    char *osname;

      

    char *csum;

    OSTree checksum of tree

     

    int deployserial;

    How many times this particular csum appears in deployment list

     

    char *bootcsum;

    Checksum of kernel+initramfs

     

    int bootserial;

    An integer assigned to this tree per its ${bootcsum}

     

    OstreeBootconfigParser *bootconfig;

    Bootloader configuration

     

    GKeyFile *origin;

    How to construct an upgraded version of this tree

     

    OstreeDeploymentUnlockedState unlocked;

    The unlocked state

     

    gboolean staged;

    TRUE iff this deployment is staged

     

    gboolean finalization_locked;

      

    char **overlay_initrds;

    Checksums of staged additional initrds for this deployment

     

    char *overlay_initrds_id;

    Unique ID generated from initrd checksums; used to compare deployments

     
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-diff.html b/reference/ostree-ostree-diff.html new file mode 100644 index 0000000000..a6b31877df --- /dev/null +++ b/reference/ostree-ostree-diff.html @@ -0,0 +1,369 @@ + + + + +ostree-diff: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-diff

    +

    ostree-diff

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeDiffItem * + +ostree_diff_item_ref () +
    +void + +ostree_diff_item_unref () +
    +gboolean + +ostree_diff_dirs () +
    +gboolean + +ostree_diff_dirs_with_options () +
    +void + +ostree_diff_print () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + +
    enumOstreeDiffFlags
    structOstreeDiffItem
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_diff_item_ref ()

    +
    OstreeDiffItem *
    +ostree_diff_item_ref (OstreeDiffItem *diffitem);
    +
    +
    +
    +

    ostree_diff_item_unref ()

    +
    void
    +ostree_diff_item_unref (OstreeDiffItem *diffitem);
    +
    +
    +
    +

    ostree_diff_dirs ()

    +
    gboolean
    +ostree_diff_dirs (OstreeDiffFlags flags,
    +                  GFile *a,
    +                  GFile *b,
    +                  GPtrArray *modified,
    +                  GPtrArray *removed,
    +                  GPtrArray *added,
    +                  GCancellable *cancellable,
    +                  GError **error);
    +

    Compute the difference between directory a + and b + as 3 separate +sets of OstreeDiffItem in modified +, removed +, and added +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    flags

    Flags

     

    a

    First directory path, or NULL

     

    b

    First directory path

     

    modified

    Modified files.

    [element-type OstreeDiffItem]

    removed

    Removed files.

    [element-type Gio.File]

    added

    Added files.

    [element-type Gio.File]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_diff_dirs_with_options ()

    +
    gboolean
    +ostree_diff_dirs_with_options (OstreeDiffFlags flags,
    +                               GFile *a,
    +                               GFile *b,
    +                               GPtrArray *modified,
    +                               GPtrArray *removed,
    +                               GPtrArray *added,
    +                               OstreeDiffDirsOptions *options,
    +                               GCancellable *cancellable,
    +                               GError **error);
    +

    Compute the difference between directory a + and b + as 3 separate +sets of OstreeDiffItem in modified +, removed +, and added +.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    flags

    Flags

     

    a

    First directory path, or NULL

     

    b

    First directory path

     

    modified

    Modified files.

    [element-type OstreeDiffItem]

    removed

    Removed files.

    [element-type Gio.File]

    added

    Added files.

    [element-type Gio.File]

    cancellable

    Cancellable

     

    options

    Options.

    [allow-none]

    error

    Error

     
    +
    +

    Since: 2017.4

    +
    +
    +
    +

    ostree_diff_print ()

    +
    void
    +ostree_diff_print (GFile *a,
    +                   GFile *b,
    +                   GPtrArray *modified,
    +                   GPtrArray *removed,
    +                   GPtrArray *added);
    +

    Print the contents of a diff to stdout.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    a

    First directory path

     

    b

    First directory path

     

    modified

    Modified files.

    [element-type OstreeDiffItem]

    removed

    Removed files.

    [element-type Gio.File]

    added

    Added files.

    [element-type Gio.File]
    +
    +
    +
    +
    +

    Types and Values

    +
    +

    enum OstreeDiffFlags

    +
    +

    Members

    +
    +++++ + + + + + + + + + + + + +

    OSTREE_DIFF_FLAGS_NONE

      

    OSTREE_DIFF_FLAGS_IGNORE_XATTRS

      
    +
    +
    +
    +
    +

    struct OstreeDiffItem

    +
    struct OstreeDiffItem {
    +  gint refcount; /* atomic */
    +
    +  GFile *src;
    +  GFile *target;
    +
    +  GFileInfo *src_info;
    +  GFileInfo *target_info;
    +
    +  char *src_checksum;
    +  char *target_checksum;
    +};
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-kernel-args.html b/reference/ostree-ostree-kernel-args.html new file mode 100644 index 0000000000..1708a69006 --- /dev/null +++ b/reference/ostree-ostree-kernel-args.html @@ -0,0 +1,1005 @@ + + + + +ostree-kernel-args: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-kernel-args

    +

    ostree-kernel-args

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +void + +ostree_kernel_args_free () +
    +OstreeKernelArgs * + +ostree_kernel_args_new () +
    +void + +ostree_kernel_args_cleanup () +
    +void + +ostree_kernel_args_replace_take () +
    +void + +ostree_kernel_args_replace () +
    +void + +ostree_kernel_args_replace_argv () +
    +void + +ostree_kernel_args_append () +
    +void + +ostree_kernel_args_append_argv () +
    +void + +ostree_kernel_args_append_argv_filtered () +
    +void + +ostree_kernel_args_append_if_missing () +
    +gboolean + +ostree_kernel_args_new_replace () +
    +gboolean + +ostree_kernel_args_delete () +
    +gboolean + +ostree_kernel_args_delete_key_entry () +
    +gboolean + +ostree_kernel_args_append_proc_cmdline () +
    +void + +ostree_kernel_args_parse_append () +
    const char * + +ostree_kernel_args_get_last_value () +
    +OstreeKernelArgs * + +ostree_kernel_args_from_string () +
    +char ** + +ostree_kernel_args_to_strv () +
    +char * + +ostree_kernel_args_to_string () +
    +gboolean + +ostree_kernel_args_contains () +
    +gboolean + +ostree_kernel_args_delete_if_present () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
     OstreeKernelArgs
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_kernel_args_free ()

    +
    void
    +ostree_kernel_args_free (OstreeKernelArgs *kargs);
    +

    Frees the kargs structure

    +
    +

    Parameters

    +
    +++++ + + + + + +

    kargs

    An OstreeKernelArgs that represents kernel arguments

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_new ()

    +
    OstreeKernelArgs *
    +ostree_kernel_args_new (void);
    +

    Initializes a new OstreeKernelArgs structure and returns it

    +

    [skip]

    +
    +

    Returns

    +

    A newly created OstreeKernelArgs for kernel arguments.

    +

    [transfer full]

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_cleanup ()

    +
    void
    +ostree_kernel_args_cleanup (void *loc);
    +

    Frees the OstreeKernelArgs structure pointed by *loc

    +
    +

    Parameters

    +
    +++++ + + + + + +

    loc

    Address of an OstreeKernelArgs pointer

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_replace_take ()

    +
    void
    +ostree_kernel_args_replace_take (OstreeKernelArgs *kargs,
    +                                 char *arg);
    +

    Finds and replaces the old key if arg + is already in the hash table, +otherwise adds arg + as new key and split_keyeq (arg) as value. +Note that when replacing old key, the old values are freed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair for replacement.

    [transfer full]
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_replace ()

    +
    void
    +ostree_kernel_args_replace (OstreeKernelArgs *kargs,
    +                            const char *arg);
    +

    Finds and replaces the old key if arg + is already in the hash table, +otherwise adds arg + as new key and split_keyeq (arg) as value. +Note that when replacing old key value pair, the old values are freed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair for replacement

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_replace_argv ()

    +
    void
    +ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs,
    +                                 char **argv);
    +

    Finds and replaces each non-null arguments of argv + in the hash table, +otherwise adds individual arg as new key and split_keyeq (arg) as value. +Note that when replacing old key value pair, the old values are freed.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    argv

    an array of key or key/value pairs

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_append ()

    +
    void
    +ostree_kernel_args_append (OstreeKernelArgs *kargs,
    +                           const char *arg);
    +

    Appends arg + which is in the form of key=value pair to the hash table kargs->table +(appends to the value list if key is already in the hash table) +and appends key to kargs->order if it is not in the hash table already.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to be added

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_append_argv ()

    +
    void
    +ostree_kernel_args_append_argv (OstreeKernelArgs *kargs,
    +                                char **argv);
    +

    Appends each value in argv + to the corresponding value array and +appends key to kargs->order if it is not in the hash table already.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    argv

    an array of key=value argument pairs.

    [array zero-terminated=1]
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_append_argv_filtered ()

    +
    void
    +ostree_kernel_args_append_argv_filtered
    +                               (OstreeKernelArgs *kargs,
    +                                char **argv,
    +                                char **prefixes);
    +

    Appends each argument that does not have one of the prefixes + as prefix to the kargs +

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    argv

    an array of key=value argument pairs.

    [array zero-terminated=1]

    prefixes

    an array of prefix strings.

    [array zero-terminated=1]
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_append_if_missing ()

    +
    void
    +ostree_kernel_args_append_if_missing (OstreeKernelArgs *kargs,
    +                                      const char *arg);
    +

    Appends arg + which is in the form of key=value pair to the hash table kargs->table +(appends to the value list if key is not in the hash table) +and appends key to kargs->order if it is not in the hash table.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to be added

     
    +
    +

    Since: 2022.5

    +
    +
    +
    +

    ostree_kernel_args_new_replace ()

    +
    gboolean
    +ostree_kernel_args_new_replace (OstreeKernelArgs *kargs,
    +                                const char *arg,
    +                                GError **error);
    +

    This function implements the basic logic behind key/value pair +replacement. Do note that the arg need to be properly formatted

    +

    When replacing key with exact one value, the arg can be in +the form: +key, key=new_val, or key=old_val=new_val +The first one swaps the old_val with the key to an empty value +The second and third replace the old_val into the new_val

    +

    When replacing key with multiple values, the arg can only be +in the form of: +key=old_val=new_val. Unless there is a special case where +there is an empty value associated with the key, then +key=new_val will work because old_val is empty. The empty +val will be swapped with the new_val in that case

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    OstreeKernelArgs instance

     

    arg

    a string argument

     

    error

    error instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure (and in some other instances such as:

    +
      +
    1. key not found in kargs +

    2. +
    3. old value not found when arg +is in the form of key=old_val=new_val

    4. +
    5. multiple old values found when arg +is in the form of key=old_val)

    6. +
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_delete ()

    +
    gboolean
    +ostree_kernel_args_delete (OstreeKernelArgs *kargs,
    +                           const char *arg,
    +                           GError **error);
    +

    There are few scenarios being handled for deletion:

    +

    1: for input arg with a single key(i.e without = for split), + the key/value pair will be deleted if there is only + one value that is associated with the key

    +

    2: for input arg wth key/value pair, the specific key + value pair will be deleted from the pointer array + if those exist.

    +

    3: If the found key has only one value + associated with it, the key entry in the table will also + be removed, and the key will be removed from order table

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair for deletion

     

    error

    an GError instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_delete_key_entry ()

    +
    gboolean
    +ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs,
    +                                     const char *key,
    +                                     GError **error);
    +

    This function removes the key entry from the hashtable +as well from the order pointer array inside kargs

    +

    Note: since both table and order inside kernel args +are with free function, no extra free functions are +being called as they are done automatically by GLib

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    an OstreeKernelArgs instance

     

    key

    the key to remove

     

    error

    an GError instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_append_proc_cmdline ()

    +
    gboolean
    +ostree_kernel_args_append_proc_cmdline
    +                               (OstreeKernelArgs *kargs,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Appends the command line arguments in the file "/proc/cmdline" +that does not have "BOOT_IMAGE=" and "initrd=" as prefixes to the kargs +

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    cancellable

    optional GCancellable object, NULL to ignore

     

    error

    an GError instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_parse_append ()

    +
    void
    +ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
    +                                 const char *options);
    +

    Parses options + by separating it by whitespaces and appends each argument to kargs +

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    options

    a string representing command line arguments

     
    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_get_last_value ()

    +
    const char *
    +ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs,
    +                                   const char *key);
    +

    Finds and returns the last element of value array +corresponding to the key + in kargs + hash table. Note that the application +will be terminated if the key + is found but the value array is empty

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    key

    a key to look for in kargs +hash table

     
    +
    +
    +

    Returns

    +

    NULL if key +is not found in the kargs +hash table, +otherwise returns last element of value array corresponding to key +.

    +

    [nullable]

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_from_string ()

    +
    OstreeKernelArgs *
    +ostree_kernel_args_from_string (const char *options);
    +

    Initializes a new OstreeKernelArgs then parses and appends options + +to the empty OstreeKernelArgs

    +

    [skip]

    +
    +

    Parameters

    +
    +++++ + + + + + +

    options

    a string representing command line arguments

     
    +
    +
    +

    Returns

    +

    newly allocated OstreeKernelArgs with options +appended.

    +

    [transfer full]

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_to_strv ()

    +
    char **
    +ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
    +

    Extracts all key value pairs in kargs + and appends to a temporary +array in forms of "key=value" or "key" if value is NULL, and returns +the temporary array with the GPtrArray wrapper freed

    +
    +

    Parameters

    +
    +++++ + + + + + +

    kargs

    a OstreeKernelArgs instance

     
    +
    +
    +

    Returns

    +

    an array of "key=value" pairs or "key" if value is NULL.

    +

    [transfer full]

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_to_string ()

    +
    char *
    +ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
    +

    Extracts all key value pairs in kargs + and appends to a temporary +GString in forms of "key=value" or "key" if value is NULL separated +by a single whitespace, and returns the temporary string with the +GString wrapper freed

    +

    Note: the application will be terminated if one of the values array +in kargs + is NULL

    +
    +

    Parameters

    +
    +++++ + + + + + +

    kargs

    a OstreeKernelArgs instance

     
    +
    +
    +

    Returns

    +

    a string of "key=value" pairs or "key" if value is NULL, +separated by single whitespaces.

    +

    [transfer full]

    +
    +

    Since: 2019.3

    +
    +
    +
    +

    ostree_kernel_args_contains ()

    +
    gboolean
    +ostree_kernel_args_contains (OstreeKernelArgs *kargs,
    +                             const char *arg);
    +

    Search for arg + which is in the form of key=value pair at the hash table kargs->table +and returns true if finds it.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to check

     
    +
    +
    +

    Returns

    +

    TRUE if arg +is contained in kargs +, FALSE otherwise.

    +
    +

    Since: 2022.7

    +
    +
    +
    +

    ostree_kernel_args_delete_if_present ()

    +
    gboolean
    +ostree_kernel_args_delete_if_present (OstreeKernelArgs *kargs,
    +                                      const char *arg,
    +                                      GError **error);
    +

    Deletes arg + which is in the form of key=value pair from the hash table kargs->table.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    kargs

    a OstreeKernelArgs instance

     

    arg

    key or key/value pair to be deleted

     

    error

    an GError instance

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE on failure

    +
    +

    Since: 2022.7

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeKernelArgs

    +
    typedef struct _OstreeKernelArgs OstreeKernelArgs;
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-ref.html b/reference/ostree-ostree-ref.html new file mode 100644 index 0000000000..90003270bf --- /dev/null +++ b/reference/ostree-ostree-ref.html @@ -0,0 +1,373 @@ + + + + +ostree-ref: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-ref

    +

    ostree-ref

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +OstreeCollectionRef * + +ostree_collection_ref_new () +
    +OstreeCollectionRef * + +ostree_collection_ref_dup () +
    +void + +ostree_collection_ref_free () +
    +guint + +ostree_collection_ref_hash () +
    +gboolean + +ostree_collection_ref_equal () +
    +OstreeCollectionRef ** + +ostree_collection_ref_dupv () +
    +void + +ostree_collection_ref_freev () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    typedefOstreeCollectionRefv
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_collection_ref_new ()

    +
    OstreeCollectionRef *
    +ostree_collection_ref_new (const gchar *collection_id,
    +                           const gchar *ref_name);
    +

    Create a new OstreeCollectionRef containing (collection_id +, ref_name +). If +collection_id + is NULL, this is equivalent to a plain ref name string (not a +refspec; no remote name is included), which can be used for non-P2P +operations.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    collection_id

    a collection ID, or NULL for a plain ref.

    [nullable]

    ref_name

    a ref name

     
    +
    +
    +

    Returns

    +

    a new OstreeCollectionRef.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_dup ()

    +
    OstreeCollectionRef *
    +ostree_collection_ref_dup (const OstreeCollectionRef *ref);
    +

    Create a copy of the given ref +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    ref

    an OstreeCollectionRef.

    [not nullable]
    +
    +
    +

    Returns

    +

    a newly allocated copy of ref +.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_free ()

    +
    void
    +ostree_collection_ref_free (OstreeCollectionRef *ref);
    +

    Free the given ref +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    ref

    an OstreeCollectionRef.

    [transfer full]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_hash ()

    +
    guint
    +ostree_collection_ref_hash (gconstpointer ref);
    +

    Hash the given ref +. This function is suitable for use with GHashTable. +ref + must be non-NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    ref

    an OstreeCollectionRef.

    [not nullable][type OstreeCollectionRef]
    +
    +
    +

    Returns

    +

    hash value for ref +

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_equal ()

    +
    gboolean
    +ostree_collection_ref_equal (gconstpointer ref1,
    +                             gconstpointer ref2);
    +

    Compare ref1 + and ref2 + and return TRUE if they have the same collection ID and +ref name, and FALSE otherwise. Both ref1 + and ref2 + must be non-NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    ref1

    an OstreeCollectionRef.

    [not nullable][type OstreeCollectionRef]

    ref2

    another OstreeCollectionRef.

    [not nullable][type OstreeCollectionRef]
    +
    +
    +

    Returns

    +

    TRUE if ref1 +and ref2 +are equal, FALSE otherwise

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_dupv ()

    +
    OstreeCollectionRef **
    +ostree_collection_ref_dupv (const OstreeCollectionRef *const *refs);
    +

    Copy an array of OstreeCollectionRefs, including deep copies of all its +elements. refs + must be NULL-terminated; it may be empty, but must not be +NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    refs

    NULL-terminated array of OstreeCollectionRefs.

    [array zero-terminated=1]
    +
    +
    +

    Returns

    +

    a newly allocated copy of refs +.

    +

    [transfer full][array zero-terminated=1]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_collection_ref_freev ()

    +
    void
    +ostree_collection_ref_freev (OstreeCollectionRef **refs);
    +

    Free the given array of refs +, including freeing all its elements. refs + +must be NULL-terminated; it may be empty, but must not be NULL.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    refs

    an array of OstreeCollectionRefs.

    [transfer full][array zero-terminated=1]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeCollectionRefv

    +
    typedef OstreeCollectionRef **OstreeCollectionRefv;
    +
    +

    A NULL-terminated array of OstreeCollectionRef instances, designed to +be used with g_auto():

    +
    + + + + + + + +
    1
    g_auto(OstreeCollectionRefv) refs = NULL;
    +
    + +

    +

    Since: 2018.6

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-remote.html b/reference/ostree-ostree-remote.html new file mode 100644 index 0000000000..5cfd768b5d --- /dev/null +++ b/reference/ostree-ostree-remote.html @@ -0,0 +1,230 @@ + + + + +ostree-remote: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-remote

    +

    ostree-remote

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + +
    +OstreeRemote * + +ostree_remote_ref () +
    +void + +ostree_remote_unref () +
    const gchar * + +ostree_remote_get_name () +
    +gchar * + +ostree_remote_get_url () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    structOstreeRemote
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_remote_ref ()

    +
    OstreeRemote *
    +ostree_remote_ref (OstreeRemote *remote);
    +

    Increase the reference count on the given remote +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    remote

    an OstreeRemote

     
    +
    +
    +

    Returns

    +

    a copy of remote +, for convenience.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_remote_unref ()

    +
    void
    +ostree_remote_unref (OstreeRemote *remote);
    +

    Decrease the reference count on the given remote + and free it if the +reference count reaches 0.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    remote

    an OstreeRemote.

    [transfer full]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_remote_get_name ()

    +
    const gchar *
    +ostree_remote_get_name (OstreeRemote *remote);
    +

    Get the human-readable name of the remote. This is what the user configured, +if the remote was explicitly configured; and will otherwise be a stable, +arbitrary, string.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    remote

    an OstreeRemote

     
    +
    +
    +

    Returns

    +

    remote’s name

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_remote_get_url ()

    +
    gchar *
    +ostree_remote_get_url (OstreeRemote *remote);
    +

    Get the URL from the remote.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    remote

    an OstreeRemote

     
    +
    +
    +

    Returns

    +

    the remote's URL.

    +

    [transfer full][nullable]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    Types and Values

    +
    +

    struct OstreeRemote

    +
    struct OstreeRemote {
    +  int ref_count;      /* atomic */
    +  char *name;         /* (not nullable) */
    +  char *refspec_name; /* (nullable) */
    +  char *group;        /* group name in options (not nullable) */
    +  char *keyring;      /* keyring name ($refspec_name.trustedkeys.gpg) (not nullable) */
    +  GFile *file;        /* NULL if remote defined in repo/config */
    +  GKeyFile *options;
    +};
    +
    +

    This represents the configuration for a single remote repository. Currently, +remotes can only be passed around as (reference counted) opaque handles. In +future, more API may be added to create and interrogate them.

    +

    Since: 2018.6

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-repo-file.html b/reference/ostree-ostree-repo-file.html new file mode 100644 index 0000000000..365900fb6f --- /dev/null +++ b/reference/ostree-ostree-repo-file.html @@ -0,0 +1,512 @@ + + + + +ostree-repo-file: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-repo-file

    +

    ostree-repo-file

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +gboolean + +ostree_repo_file_ensure_resolved () +
    +gboolean + +ostree_repo_file_get_xattrs () +
    +OstreeRepo * + +ostree_repo_file_get_repo () +
    +OstreeRepoFile * + +ostree_repo_file_get_root () +
    +void + +ostree_repo_file_tree_set_metadata () +
    const char * + +ostree_repo_file_tree_get_contents_checksum () +
    const char * + +ostree_repo_file_tree_get_metadata_checksum () +
    +GVariant * + +ostree_repo_file_tree_get_contents () +
    +GVariant * + +ostree_repo_file_tree_get_metadata () +
    const char * + +ostree_repo_file_get_checksum () +
    +int + +ostree_repo_file_tree_find_child () +
    +gboolean + +ostree_repo_file_tree_query_child () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + +
    typedefOstreeRepoFile
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_repo_file_ensure_resolved ()

    +
    gboolean
    +ostree_repo_file_ensure_resolved (OstreeRepoFile *self,
    +                                  GError **error);
    +

    Ensure that the backing metadata is loaded.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    self

    A repo file

     

    error

    Error

     
    +
    +
    +

    Returns

    +

    FALSE if the operation failed, TRUE otherwise

    +
    +
    +
    +
    +

    ostree_repo_file_get_xattrs ()

    +
    gboolean
    +ostree_repo_file_get_xattrs (OstreeRepoFile *self,
    +                             GVariant **out_xattrs,
    +                             GCancellable *cancellable,
    +                             GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    OstreeRepoFile

     

    out_xattrs

    the extended attributes.

    [out][optional]

    cancellable

    Cancellable

     

    error

    Error

     
    +
    +
    +
    +
    +

    ostree_repo_file_get_repo ()

    +
    OstreeRepo *
    +ostree_repo_file_get_repo (OstreeRepoFile *self);
    +
    +

    Returns

    +

    Repository.

    +

    [transfer none]

    +
    +
    +
    +
    +

    ostree_repo_file_get_root ()

    +
    OstreeRepoFile *
    +ostree_repo_file_get_root (OstreeRepoFile *self);
    +
    +

    Returns

    +

    The root directory for the commit referenced by this file.

    +

    [transfer none]

    +
    +
    +
    +
    +

    ostree_repo_file_tree_set_metadata ()

    +
    void
    +ostree_repo_file_tree_set_metadata (OstreeRepoFile *self,
    +                                    const char *checksum,
    +                                    GVariant *metadata);
    +

    Replace the metadata checksum and metadata object.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +
    +
    +

    ostree_repo_file_tree_get_contents_checksum ()

    +
    const char *
    +ostree_repo_file_tree_get_contents_checksum
    +                               (OstreeRepoFile *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The SHA256 digest of the content object, or NULL if this is not a +directory.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_repo_file_tree_get_metadata_checksum ()

    +
    const char *
    +ostree_repo_file_tree_get_metadata_checksum
    +                               (OstreeRepoFile *self);
    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The SHA256 digest of the metadata object, or NULL if this is not a +directory.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_repo_file_tree_get_contents ()

    +
    GVariant *
    +ostree_repo_file_tree_get_contents (OstreeRepoFile *self);
    +

    This API will return NULL if the file is not "resolved" i.e. in a loaded +state. It will also return NULL if this path is not a directory tree.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The GVariant representing the children of this directory.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_repo_file_tree_get_metadata ()

    +
    GVariant *
    +ostree_repo_file_tree_get_metadata (OstreeRepoFile *self);
    +

    This API will return NULL if the file is not "resolved" i.e. in a loaded +state. It will also return NULL if this path is not a directory tree.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    self

    A repo file

     
    +
    +
    +

    Returns

    +

    The GVariant representing the metadata for this directory.

    +

    [nullable]

    +
    +
    +
    +
    +

    ostree_repo_file_get_checksum ()

    +
    const char *
    +ostree_repo_file_get_checksum (OstreeRepoFile *self);
    +
    +
    +
    +

    ostree_repo_file_tree_find_child ()

    +
    int
    +ostree_repo_file_tree_find_child (OstreeRepoFile *self,
    +                                  const char *name,
    +                                  gboolean *is_dir,
    +                                  GVariant **out_container);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    OstreeRepoFile

     

    name

    name of the child

     

    is_dir

    .

    [out caller-allocates]

    out_container

    .

    [out]
    +
    +
    +
    +
    +

    ostree_repo_file_tree_query_child ()

    +
    gboolean
    +ostree_repo_file_tree_query_child (OstreeRepoFile *self,
    +                                   int n,
    +                                   const char *attributes,
    +                                   GFileQueryInfoFlags flags,
    +                                   GFileInfo **out_info,
    +                                   GCancellable *cancellable,
    +                                   GError **error);
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    OstreeRepoFile

     

    n

    the child number

     

    attributes

    an attribute string to match, see g_file_attribute_matcher_new()

     

    flags

    a GFileQueryInfoFlags

     

    out_info

    the GFileInfo of the child.

    [out][transfer full][optional]

    cancellable

    a GCancellable or NULL

     

    error

    a GError or NULL

     
    +
    +
    +

    Returns

    +

    TRUE on success and the out_info +is set, FALSE otherwise.

    +
    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeRepoFile

    +
    typedef struct OstreeRepoFile OstreeRepoFile;
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-repo-finder.html b/reference/ostree-ostree-repo-finder.html new file mode 100644 index 0000000000..337e70bd62 --- /dev/null +++ b/reference/ostree-ostree-repo-finder.html @@ -0,0 +1,577 @@ + + + + +ostree-repo-finder: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-repo-finder

    +

    ostree-repo-finder

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +void + +ostree_repo_finder_resolve_async () +
    +GPtrArray * + +ostree_repo_finder_resolve_finish () +
    +void + +ostree_repo_finder_resolve_all_async () +
    +GPtrArray * + +ostree_repo_finder_resolve_all_finish () +
    +OstreeRepoFinderResult * + +ostree_repo_finder_result_new () +
    +OstreeRepoFinderResult * + +ostree_repo_finder_result_dup () +
    +void + +ostree_repo_finder_result_free () +
    +gint + +ostree_repo_finder_result_compare () +
    +void + +ostree_repo_finder_result_freev () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + +
     OstreeRepoFinder
    typedefOstreeRepoFinderResultv
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_repo_finder_resolve_async ()

    +
    void
    +ostree_repo_finder_resolve_async (OstreeRepoFinder *self,
    +                                  const OstreeCollectionRef *const *refs,
    +                                  OstreeRepo *parent_repo,
    +                                  GCancellable *cancellable,
    +                                  GAsyncReadyCallback callback,
    +                                  gpointer user_data);
    +

    Find reachable remote URIs which claim to provide any of the given refs +. The +specific method for finding the remotes depends on the OstreeRepoFinder +implementation.

    +

    Any remote which is found and which claims to support any of the given refs + +will be returned in the results. It is possible that a remote claims to +support a given ref, but turns out not to — it is not possible to verify this +until ostree_repo_pull_from_remotes_async() is called.

    +

    The returned results will be sorted with the most useful first — this is +typically the remote which claims to provide the most refs +, at the lowest +latency.

    +

    Each result contains a mapping of refs + to the checksums of the commits +which the result provides. If the result provides the latest commit for a ref +across all of the results, the checksum will be set. Otherwise, if the +result provides an outdated commit, or doesn’t provide a given ref at all, +the checksum will not be set. Results which provide none of the requested +refs + may be listed with an empty refs map.

    +

    Pass the results to ostree_repo_pull_from_remotes_async() to pull the given +refs + from those remotes.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepoFinder

     

    refs

    non-empty array of collection–ref pairs to find remotes for.

    [array zero-terminated=1]

    parent_repo

    the local repository which the refs are being resolved for, +which provides configuration information and GPG keys.

    [transfer none]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    callback

    asynchronous completion callback

     

    user_data

    data to pass to callback +

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_resolve_finish ()

    +
    GPtrArray *
    +ostree_repo_finder_resolve_finish (OstreeRepoFinder *self,
    +                                   GAsyncResult *result,
    +                                   GError **error);
    +

    Get the results from a ostree_repo_finder_resolve_async() operation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepoFinder

     

    result

    GAsyncResult from the callback

     

    error

    return location for a GError

     
    +
    +
    +

    Returns

    +

    array of zero +or more results.

    +

    [transfer full][element-type OstreeRepoFinderResult]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_resolve_all_async ()

    +
    void
    +ostree_repo_finder_resolve_all_async (OstreeRepoFinder *const *finders,
    +                                      const OstreeCollectionRef *const *refs,
    +                                      OstreeRepo *parent_repo,
    +                                      GCancellable *cancellable,
    +                                      GAsyncReadyCallback callback,
    +                                      gpointer user_data);
    +

    A version of ostree_repo_finder_resolve_async() which queries one or more +finders + in parallel and combines the results.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    finders

    non-empty array of OstreeRepoFinders.

    [array zero-terminated=1]

    refs

    non-empty array of collection–ref pairs to find remotes for.

    [array zero-terminated=1]

    parent_repo

    the local repository which the refs are being resolved for, +which provides configuration information and GPG keys.

    [transfer none]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    callback

    asynchronous completion callback

     

    user_data

    data to pass to callback +

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_resolve_all_finish ()

    +
    GPtrArray *
    +ostree_repo_finder_resolve_all_finish (GAsyncResult *result,
    +                                       GError **error);
    +

    Get the results from a ostree_repo_finder_resolve_all_async() operation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    result

    GAsyncResult from the callback

     

    error

    return location for a GError

     
    +
    +
    +

    Returns

    +

    array of zero +or more results.

    +

    [transfer full][element-type OstreeRepoFinderResult]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_result_new ()

    +
    OstreeRepoFinderResult *
    +ostree_repo_finder_result_new (OstreeRemote *remote,
    +                               OstreeRepoFinder *finder,
    +                               gint priority,
    +                               GHashTable *ref_to_checksum,
    +                               GHashTable *ref_to_timestamp,
    +                               guint64 summary_last_modified);
    +

    Create a new OstreeRepoFinderResult instance. The semantics for the arguments +are as described in the OstreeRepoFinderResult documentation.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    remote

    an OstreeRemote containing the transport details +for the result.

    [transfer none]

    finder

    the OstreeRepoFinder instance which produced the +result.

    [transfer none]

    priority

    static priority of the result, where higher numbers indicate lower +priority

     

    ref_to_checksum

    map of collection–ref pairs to checksums provided by this result.

    [element-type OstreeCollectionRef utf8][transfer none]

    ref_to_timestamp

    (element-type OstreeCollectionRef guint64) (nullable) +(transfer none): map of collection–ref pairs to timestamps provided by this +result

     

    summary_last_modified

    Unix timestamp (seconds since the epoch, UTC) when +the summary file for the result was last modified, or 0 if this is unknown

     
    +
    +
    +

    Returns

    +

    a new OstreeRepoFinderResult.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_result_dup ()

    +
    OstreeRepoFinderResult *
    +ostree_repo_finder_result_dup (OstreeRepoFinderResult *result);
    +

    Copy an OstreeRepoFinderResult.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    result

    an OstreeRepoFinderResult to copy.

    [transfer none]
    +
    +
    +

    Returns

    +

    a newly allocated copy of result +.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_result_free ()

    +
    void
    +ostree_repo_finder_result_free (OstreeRepoFinderResult *result);
    +

    Free the given result +.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    result

    an OstreeRepoFinderResult.

    [transfer full]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_result_compare ()

    +
    gint
    +ostree_repo_finder_result_compare (const OstreeRepoFinderResult *a,
    +                                   const OstreeRepoFinderResult *b);
    +

    Compare two OstreeRepoFinderResult instances to work out which one is better +to pull from, and hence needs to be ordered before the other.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    a

    an OstreeRepoFinderResult

     

    b

    an OstreeRepoFinderResult

     
    +
    +
    +

    Returns

    +

    <0 if a +is ordered before b +, 0 if they are ordered equally, +>0 if b +is ordered before a +

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_finder_result_freev ()

    +
    void
    +ostree_repo_finder_result_freev (OstreeRepoFinderResult **results);
    +

    Free the given results + array, freeing each element and the container.

    +
    +

    Parameters

    +
    +++++ + + + + + +

    results

    an OstreeRepoFinderResult.

    [array zero-terminated=1][transfer full]
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    Types and Values

    +
    +

    OstreeRepoFinder

    +
    typedef struct _OstreeRepoFinder OstreeRepoFinder;
    +
    +
    +
    +

    OstreeRepoFinderResultv

    +
    typedef OstreeRepoFinderResult **OstreeRepoFinderResultv;
    +
    +

    A NULL-terminated array of OstreeRepoFinderResult instances, designed to +be used with g_auto():

    +
    + + + + + + + +
    1
    g_auto(OstreeRepoFinderResultv) results = NULL;
    +
    + +

    +

    Since: 2018.6

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-repo-remote-finder.html b/reference/ostree-ostree-repo-remote-finder.html new file mode 100644 index 0000000000..74533e4752 --- /dev/null +++ b/reference/ostree-ostree-repo-remote-finder.html @@ -0,0 +1,516 @@ + + + + +ostree-repo-remote-finder: OSTree API references + + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-repo-remote-finder

    +

    ostree-repo-remote-finder

    +
    +
    +

    Functions

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + +
    +void + +ostree_repo_find_remotes_async () +
    +OstreeRepoFinderResult ** + +ostree_repo_find_remotes_finish () +
    +void + +ostree_repo_pull_from_remotes_async () +
    +gboolean + +ostree_repo_pull_from_remotes_finish () +
    +OstreeRemote * + +ostree_repo_resolve_keyring_for_collection () +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + +
    #defineOSTREE_REPO_METADATA_REF
    #defineOSTREE_META_KEY_DEPLOY_COLLECTION_ID
    +
    +
    +

    Description

    +
    +
    +

    Functions

    +
    +

    ostree_repo_find_remotes_async ()

    +
    void
    +ostree_repo_find_remotes_async (OstreeRepo *self,
    +                                const OstreeCollectionRef *const *refs,
    +                                GVariant *options,
    +                                OstreeRepoFinder **finders,
    +                                OstreeAsyncProgress *progress,
    +                                GCancellable *cancellable,
    +                                GAsyncReadyCallback callback,
    +                                gpointer user_data);
    +

    Find reachable remote URIs which claim to provide any of the given named +refs +. This will search for configured remotes (OstreeRepoFinderConfig), +mounted volumes (OstreeRepoFinderMount) and (if enabled at compile time) +local network peers (OstreeRepoFinderAvahi). In order to use a custom +configuration of OstreeRepoFinder instances, call +ostree_repo_finder_resolve_all_async() on them individually.

    +

    Any remote which is found and which claims to support any of the given refs + +will be returned in the results. It is possible that a remote claims to +support a given ref, but turns out not to — it is not possible to verify this +until ostree_repo_pull_from_remotes_async() is called.

    +

    The returned results will be sorted with the most useful first — this is +typically the remote which claims to provide the most of refs +, at the lowest +latency.

    +

    Each result contains a list of the subset of refs + it claims to provide. It +is possible for a non-empty list of results to be returned, but for some of +refs + to not be listed in any of the results. Callers must check for this.

    +

    Pass the results to ostree_repo_pull_from_remotes_async() to pull the given refs + +from those remotes.

    +

    The following options + are currently defined:

    +
      +
    • override-commit-ids (as): Array of specific commit IDs to fetch. The nth +commit ID applies to the nth ref, so this must be the same length as refs +, if +provided.

    • +
    • n-network-retries (u): Number of times to retry each download on +receiving a transient network error, such as a socket timeout; default is +5, 0 means return errors without retrying. Since: 2018.6

    • +
    +

    finders + must be a non-empty NULL-terminated array of the OstreeRepoFinder +instances to use, or NULL to use the system default set of finders, which +will typically be all available finders using their default options (but +this is not guaranteed).

    +

    GPG verification of commits will be used unconditionally.

    +

    This will use the thread-default GMainContext, but will not iterate it.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    refs

    non-empty array of collection–ref pairs to find remotes for.

    [array zero-terminated=1]

    options

    a GVariant a{sv} with an extensible set of flags.

    [nullable]

    finders

    non-empty array of +OstreeRepoFinder instances to use, or NULL to use the system defaults.

    [array zero-terminated=1][transfer none]

    progress

    an OstreeAsyncProgress to update with the operation’s +progress, or NULL.

    [nullable]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    callback

    asynchronous completion callback

     

    user_data

    data to pass to callback +

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_find_remotes_finish ()

    +
    OstreeRepoFinderResult **
    +ostree_repo_find_remotes_finish (OstreeRepo *self,
    +                                 GAsyncResult *result,
    +                                 GError **error);
    +

    Finish an asynchronous pull operation started with +ostree_repo_find_remotes_async().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    result

    the asynchronous result

     

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    a potentially empty array +of OstreeRepoFinderResults, followed by a NULL terminator element; or +NULL on error.

    +

    [transfer full][array zero-terminated=1]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_pull_from_remotes_async ()

    +
    void
    +ostree_repo_pull_from_remotes_async (OstreeRepo *self,
    +                                     const OstreeRepoFinderResult *const *results,
    +                                     GVariant *options,
    +                                     OstreeAsyncProgress *progress,
    +                                     GCancellable *cancellable,
    +                                     GAsyncReadyCallback callback,
    +                                     gpointer user_data);
    +

    Pull refs from multiple remotes which have been found using +ostree_repo_find_remotes_async().

    +

    results + are expected to be in priority order, with the best remotes to pull +from listed first. ostree_repo_pull_from_remotes_async() will generally pull +from the remotes in order, but may parallelise its downloads.

    +

    If an error is encountered when pulling from a given remote, that remote will +be ignored and another will be tried instead. If any refs have not been +downloaded successfully after all remotes have been tried, G_IO_ERROR_FAILED +will be returned. The results of any successful downloads will remain cached +in the local repository.

    +

    If cancellable + is cancelled, G_IO_ERROR_CANCELLED will be returned +immediately. The results of any successfully completed downloads at that +point will remain cached in the local repository.

    +

    GPG verification of commits will be used unconditionally.

    +

    The following options + are currently defined:

    +
      +
    • flags (i): OstreeRepoPullFlags to apply to the pull operation

    • +
    • inherit-transaction (b): TRUE to inherit an ongoing transaction on +the OstreeRepo, rather than encapsulating the pull in a new one

    • +
    • depth (i): How far in the history to traverse; default is 0, -1 means infinite

    • +
    • disable-static-deltas (b): Do not use static deltas

    • +
    • http-headers (a(ss)): Additional headers to add to all HTTP requests

    • +
    • subdirs (as): Pull just these subdirectories

    • +
    • update-frequency (u): Frequency to call the async progress callback in +milliseconds, if any; only values higher than 0 are valid

    • +
    • append-user-agent (s): Additional string to append to the user agent

    • +
    • n-network-retries (u): Number of times to retry each download on receiving +a transient network error, such as a socket timeout; default is 5, 0 +means return errors without retrying. Since: 2018.6

    • +
    • ref-keyring-map (a(sss)): Array of (collection ID, ref name, keyring +remote name) tuples specifying which remote's keyring should be used when +doing GPG verification of each collection-ref. This is useful to prevent a +remote from serving malicious updates to refs which did not originate from +it. This can be a subset or superset of the refs being pulled; any ref +not being pulled will be ignored and any ref without a keyring remote +will be verified with the keyring of the remote being pulled from.

    • +
    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    results

    NULL-terminated array of remotes to +pull from, including the refs to pull from each.

    [array zero-terminated=1]

    options

    A GVariant a{sv} with an extensible set of flags.

    [nullable]

    progress

    an OstreeAsyncProgress to update with the operation’s +progress, or NULL.

    [nullable]

    cancellable

    a GCancellable, or NULL.

    [nullable]

    callback

    asynchronous completion callback

     

    user_data

    data to pass to callback +

     
    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_pull_from_remotes_finish ()

    +
    gboolean
    +ostree_repo_pull_from_remotes_finish (OstreeRepo *self,
    +                                      GAsyncResult *result,
    +                                      GError **error);
    +

    Finish an asynchronous pull operation started with +ostree_repo_pull_from_remotes_async().

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    result

    the asynchronous result

     

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    TRUE on success, FALSE otherwise

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    ostree_repo_resolve_keyring_for_collection ()

    +
    OstreeRemote *
    +ostree_repo_resolve_keyring_for_collection
    +                               (OstreeRepo *self,
    +                                const gchar *collection_id,
    +                                GCancellable *cancellable,
    +                                GError **error);
    +

    Find the GPG keyring for the given collection_id +, using the local +configuration from the given OstreeRepo. This will search the configured +remotes for ones whose collection-id key matches collection_id +, and will +return the first matching remote.

    +

    If multiple remotes match and have different keyrings, a debug message will +be emitted, and the first result will be returned. It is expected that the +keyrings should match.

    +

    If no match can be found, a G_IO_ERROR_NOT_FOUND error will be returned.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + + + + + + + + + + + +

    self

    an OstreeRepo

     

    collection_id

    the collection ID to look up a keyring for

     

    cancellable

    a GCancellable, or NULL.

    [nullable]

    error

    return location for a GError, or NULL

     
    +
    +
    +

    Returns

    +

    OstreeRemote containing the GPG keyring for +collection_id +.

    +

    [transfer full]

    +
    +

    Since: 2018.6

    +
    +
    +
    +

    Types and Values

    +
    +

    OSTREE_REPO_METADATA_REF

    +
    #define OSTREE_REPO_METADATA_REF "ostree-metadata"
    +
    +

    The name of a ref which is used to store metadata for the entire repository, +such as its expected update time (ostree.summary.expires), name, or new +GPG keys. Metadata is stored on contentless commits in the ref, and hence is +signed with the commits.

    +

    This supersedes the additional metadata dictionary in the summary file +(see ostree_repo_regenerate_summary()), as the use of a ref means that the +metadata for multiple upstream repositories can be included in a single mirror +repository, disambiguating the refs using collection IDs. In order to support +peer to peer redistribution of repository metadata, repositories must set a +collection ID (ostree_repo_set_collection_id()).

    +

    Users of OSTree may place arbitrary metadata in commits on this ref, but the +keys must be namespaced by product or developer. For example, +exampleos.end-of-life. The ostree. prefix is reserved.

    +

    Since: 2018.6

    +
    +
    +
    +

    OSTREE_META_KEY_DEPLOY_COLLECTION_ID

    +
    #define OSTREE_META_KEY_DEPLOY_COLLECTION_ID "ostree.deploy-collection-id"
    +
    +

    GVariant type s. This key can be used in the repo metadata which is stored +in OSTREE_REPO_METADATA_REF as well as in the summary. The semantics of this +are that the remote repository wants clients to update their remote config +to add this collection ID (clients can't do P2P operations involving a +remote without a collection ID configured on it, even if one is configured +on the server side). Clients must never change or remove a collection ID +already set in their remote config.

    +

    Currently, OSTree does not implement changing a remote config based on this +key, but it may do so in a later release, and until then clients such as +Flatpak may implement it.

    +

    This is a replacement for the similar metadata key implemented by flatpak, +xa.collection-id, which is now deprecated as clients which supported it had +bugs with their P2P implementations.

    +

    Since: 2018.9

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree-ostree-version.html b/reference/ostree-ostree-version.html new file mode 100644 index 0000000000..78a663ccfa --- /dev/null +++ b/reference/ostree-ostree-version.html @@ -0,0 +1,163 @@ + + + + +ostree-version: OSTree API references + + + + + + + + + + + + + + + +
    +
    +
    + + +
    +

    ostree-version

    +

    ostree-version — ostree version checking

    +
    +
    +

    Functions

    +
    ++++ + + + + +
    #define +OSTREE_CHECK_VERSION() +
    +
    +
    +

    Types and Values

    +
    ++++ + + + + + + + + + + + + + + + + + + + + + + +
    #defineOSTREE_YEAR_VERSION
    #defineOSTREE_RELEASE_VERSION
    #defineOSTREE_VERSION
    #defineOSTREE_VERSION_S
    #defineOSTREE_VERSION_HEX
    +
    +
    +

    Description

    +

    ostree provides macros to check the version of the library +at compile-time

    +
    +
    +

    Functions

    +
    +

    OSTREE_CHECK_VERSION()

    +
    #define             OSTREE_CHECK_VERSION(year,release)
    +

    Compile-time version checking. Evaluates to TRUE if the version +of ostree is equal or greater than the required one.

    +
    +

    Parameters

    +
    +++++ + + + + + + + + + + + + +

    year

    required year version

     

    release

    required release version

     
    +
    +

    Since: 2017.4

    +
    +
    +
    +

    Types and Values

    +
    +

    OSTREE_YEAR_VERSION

    +
    #define OSTREE_YEAR_VERSION (2024)
    +
    +

    ostree year version component (e.g. 2017 if OSTREE_VERSION is 2017.2)

    +

    Since: 2017.4

    +
    +
    +
    +

    OSTREE_RELEASE_VERSION

    +
    #define OSTREE_RELEASE_VERSION (6)
    +
    +

    ostree release version component (e.g. 2 if OSTREE_VERSION is 2017.2)

    +

    Since: 2017.4

    +
    +
    +
    +

    OSTREE_VERSION

    +
    #define OSTREE_VERSION (2024.6)
    +
    +

    ostree version.

    +

    Since: 2017.4

    +
    +
    +
    +

    OSTREE_VERSION_S

    +
    #define OSTREE_VERSION_S "2024.6"
    +
    +

    ostree version, encoded as a string, useful for printing and +concatenation.

    +

    Since: 2017.4

    +
    +
    +
    +

    OSTREE_VERSION_HEX

    +
    #define             OSTREE_VERSION_HEX
    +

    ostree version, encoded as an hexadecimal number, useful for +integer comparisons.

    +

    Since: 2017.4

    +
    +
    +
    + + + \ No newline at end of file diff --git a/reference/ostree.devhelp2 b/reference/ostree.devhelp2 new file mode 100644 index 0000000000..ea7a8fe5ad --- /dev/null +++ b/reference/ostree.devhelp2 @@ -0,0 +1,679 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/reference/reference.html b/reference/reference.html new file mode 100644 index 0000000000..dc305c14fe --- /dev/null +++ b/reference/reference.html @@ -0,0 +1,2226 @@ + + + + +API Reference: OSTree API references + + + + + + + + + + + + + + + + +
    +

    +API Reference

    +
    +
    +Core repository-independent functions — Create, validate, and convert core data types +
    +
    +OstreeRepo: Content-addressed object store — A git-like storage system for operating system binaries +
    +
    +In-memory modifiable filesystem tree — Modifiable filesystem tree +
    +
    +Root partition mount point — Manage physical root filesystem +
    +
    +Progress notification system for asynchronous operations — Values representing progress +
    +
    +SELinux policy management — Read SELinux policy and manage filesystem labels +
    +
    +Simple upgrade class — Upgrade OSTree systems +
    +
    +GPG signature verification results — Inspect detached GPG signatures +
    +
    +Signature management — Sign and verify commits +
    +
    +ostree-bootconfig-parser +
    +
    +ostree-chain-input-stream +
    +
    +ostree-checksum-input-stream +
    +
    +ostree-content-writer +
    +
    +ostree-deployment +
    +
    +ostree-diff +
    +
    +ostree-kernel-args +
    +
    +ostree-ref +
    +
    +ostree-remote +
    +
    +ostree-repo-file +
    +
    +ostree-repo-finder +
    +
    +ostree-repo-remote-finder +
    +
    +ostree-version — ostree version checking +
    +
    API Index
    +
    +
    +

    +API Index

    +

    A

    +

    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 A(EtDd literal 0 HcmV?d00001 diff --git a/assets/js/just-the-docs.js b/assets/js/just-the-docs.js new file mode 100644 index 0000000000..21c50817c7 --- /dev/null +++ b/assets/js/just-the-docs.js @@ -0,0 +1,497 @@ +(function (jtd, undefined) { + +// Event handling + +jtd.addEvent = function(el, type, handler) { + if (el.attachEvent) el.attachEvent('on'+type, handler); else el.addEventListener(type, handler); +} +jtd.removeEvent = function(el, type, handler) { + if (el.detachEvent) el.detachEvent('on'+type, handler); else el.removeEventListener(type, handler); +} +jtd.onReady = function(ready) { + // in case the document is already rendered + if (document.readyState!='loading') ready(); + // modern browsers + else if (document.addEventListener) document.addEventListener('DOMContentLoaded', ready); + // IE <= 8 + else document.attachEvent('onreadystatechange', function(){ + if (document.readyState=='complete') ready(); + }); +} + +// Show/hide mobile menu + +function initNav() { + jtd.addEvent(document, 'click', function(e){ + var target = e.target; + while (target && !(target.classList && target.classList.contains('nav-list-expander'))) { + target = target.parentNode; + } + if (target) { + e.preventDefault(); + target.parentNode.classList.toggle('active'); + } + }); + + const siteNav = document.getElementById('site-nav'); + const mainHeader = document.getElementById('main-header'); + const menuButton = document.getElementById('menu-button'); + + jtd.addEvent(menuButton, 'click', function(e){ + e.preventDefault(); + + if (menuButton.classList.toggle('nav-open')) { + siteNav.classList.add('nav-open'); + mainHeader.classList.add('nav-open'); + } else { + siteNav.classList.remove('nav-open'); + mainHeader.classList.remove('nav-open'); + } + }); +} +// Site search + +function initSearch() { + var request = new XMLHttpRequest(); + request.open('GET', '/ostree/assets/js/search-data.json', true); + + request.onload = function(){ + if (request.status >= 200 && request.status < 400) { + var docs = JSON.parse(request.responseText); + + lunr.tokenizer.separator = /[\s\-/]+/ + + var index = lunr(function(){ + this.ref('id'); + this.field('title', { boost: 200 }); + this.field('content', { boost: 2 }); + this.field('relUrl'); + this.metadataWhitelist = ['position'] + + for (var i in docs) { + + this.add({ + id: i, + title: docs[i].title, + content: docs[i].content, + relUrl: docs[i].relUrl + }); + } + }); + + searchLoaded(index, docs); + } else { + console.log('Error loading ajax request. Request status:' + request.status); + } + }; + + request.onerror = function(){ + console.log('There was a connection error'); + }; + + request.send(); +} + +function searchLoaded(index, docs) { + var index = index; + var docs = docs; + var searchInput = document.getElementById('search-input'); + var searchResults = document.getElementById('search-results'); + var mainHeader = document.getElementById('main-header'); + var currentInput; + var currentSearchIndex = 0; + + function showSearch() { + document.documentElement.classList.add('search-active'); + } + + function hideSearch() { + document.documentElement.classList.remove('search-active'); + } + + function update() { + currentSearchIndex++; + + var input = searchInput.value; + if (input === '') { + hideSearch(); + } else { + showSearch(); + // scroll search input into view, workaround for iOS Safari + window.scroll(0, -1); + setTimeout(function(){ window.scroll(0, 0); }, 0); + } + if (input === currentInput) { + return; + } + currentInput = input; + searchResults.innerHTML = ''; + if (input === '') { + return; + } + + var results = index.query(function (query) { + var tokens = lunr.tokenizer(input) + query.term(tokens, { + boost: 10 + }); + query.term(tokens, { + wildcard: lunr.Query.wildcard.TRAILING + }); + }); + + if ((results.length == 0) && (input.length > 2)) { + var tokens = lunr.tokenizer(input).filter(function(token, i) { + return token.str.length < 20; + }) + if (tokens.length > 0) { + results = index.query(function (query) { + query.term(tokens, { + editDistance: Math.round(Math.sqrt(input.length / 2 - 1)) + }); + }); + } + } + + if (results.length == 0) { + var noResultsDiv = document.createElement('div'); + noResultsDiv.classList.add('search-no-result'); + noResultsDiv.innerText = 'No results found'; + searchResults.appendChild(noResultsDiv); + + } else { + var resultsList = document.createElement('ul'); + resultsList.classList.add('search-results-list'); + searchResults.appendChild(resultsList); + + addResults(resultsList, results, 0, 10, 100, currentSearchIndex); + } + + function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) { + if (searchIndex != currentSearchIndex) { + return; + } + for (var i = start; i < (start + batchSize); i++) { + if (i == results.length) { + return; + } + addResult(resultsList, results[i]); + } + setTimeout(function() { + addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex); + }, batchMillis); + } + + function addResult(resultsList, result) { + var doc = docs[result.ref]; + + var resultsListItem = document.createElement('li'); + resultsListItem.classList.add('search-results-list-item'); + resultsList.appendChild(resultsListItem); + + var resultLink = document.createElement('a'); + resultLink.classList.add('search-result'); + resultLink.setAttribute('href', doc.url); + resultsListItem.appendChild(resultLink); + + var resultTitle = document.createElement('div'); + resultTitle.classList.add('search-result-title'); + resultLink.appendChild(resultTitle); + + // note: the SVG svg-doc is only loaded as a Jekyll include if site.search_enabled is true; see _includes/icons/icons.html + var resultDoc = document.createElement('div'); + resultDoc.classList.add('search-result-doc'); + resultDoc.innerHTML = ''; + resultTitle.appendChild(resultDoc); + + var resultDocTitle = document.createElement('div'); + resultDocTitle.classList.add('search-result-doc-title'); + resultDocTitle.innerHTML = doc.doc; + resultDoc.appendChild(resultDocTitle); + var resultDocOrSection = resultDocTitle; + + if (doc.doc != doc.title) { + resultDoc.classList.add('search-result-doc-parent'); + var resultSection = document.createElement('div'); + resultSection.classList.add('search-result-section'); + resultSection.innerHTML = doc.title; + resultTitle.appendChild(resultSection); + resultDocOrSection = resultSection; + } + + var metadata = result.matchData.metadata; + var titlePositions = []; + var contentPositions = []; + for (var j in metadata) { + var meta = metadata[j]; + if (meta.title) { + var positions = meta.title.position; + for (var k in positions) { + titlePositions.push(positions[k]); + } + } + if (meta.content) { + var positions = meta.content.position; + for (var k in positions) { + var position = positions[k]; + var previewStart = position[0]; + var previewEnd = position[0] + position[1]; + var ellipsesBefore = true; + var ellipsesAfter = true; + for (var k = 0; k < 5; k++) { + var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2); + var nextDot = doc.content.lastIndexOf('. ', previewStart - 2); + if ((nextDot >= 0) && (nextDot > nextSpace)) { + previewStart = nextDot + 1; + ellipsesBefore = false; + break; + } + if (nextSpace < 0) { + previewStart = 0; + ellipsesBefore = false; + break; + } + previewStart = nextSpace + 1; + } + for (var k = 0; k < 10; k++) { + var nextSpace = doc.content.indexOf(' ', previewEnd + 1); + var nextDot = doc.content.indexOf('. ', previewEnd + 1); + if ((nextDot >= 0) && (nextDot < nextSpace)) { + previewEnd = nextDot; + ellipsesAfter = false; + break; + } + if (nextSpace < 0) { + previewEnd = doc.content.length; + ellipsesAfter = false; + break; + } + previewEnd = nextSpace; + } + contentPositions.push({ + highlight: position, + previewStart: previewStart, previewEnd: previewEnd, + ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter + }); + } + } + } + + if (titlePositions.length > 0) { + titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] }); + resultDocOrSection.innerHTML = ''; + addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions); + } + + if (contentPositions.length > 0) { + contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] }); + var contentPosition = contentPositions[0]; + var previewPosition = { + highlight: [contentPosition.highlight], + previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd, + ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter + }; + var previewPositions = [previewPosition]; + for (var j = 1; j < contentPositions.length; j++) { + contentPosition = contentPositions[j]; + if (previewPosition.previewEnd < contentPosition.previewStart) { + previewPosition = { + highlight: [contentPosition.highlight], + previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd, + ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter + } + previewPositions.push(previewPosition); + } else { + previewPosition.highlight.push(contentPosition.highlight); + previewPosition.previewEnd = contentPosition.previewEnd; + previewPosition.ellipsesAfter = contentPosition.ellipsesAfter; + } + } + + var resultPreviews = document.createElement('div'); + resultPreviews.classList.add('search-result-previews'); + resultLink.appendChild(resultPreviews); + + var content = doc.content; + for (var j = 0; j < Math.min(previewPositions.length, 3); j++) { + var position = previewPositions[j]; + + var resultPreview = document.createElement('div'); + resultPreview.classList.add('search-result-preview'); + resultPreviews.appendChild(resultPreview); + + if (position.ellipsesBefore) { + resultPreview.appendChild(document.createTextNode('... ')); + } + addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight); + if (position.ellipsesAfter) { + resultPreview.appendChild(document.createTextNode(' ...')); + } + } + } + var resultRelUrl = document.createElement('span'); + resultRelUrl.classList.add('search-result-rel-url'); + resultRelUrl.innerText = doc.relUrl; + resultTitle.appendChild(resultRelUrl); + } + + function addHighlightedText(parent, text, start, end, positions) { + var index = start; + for (var i in positions) { + var position = positions[i]; + var span = document.createElement('span'); + span.innerHTML = text.substring(index, position[0]); + parent.appendChild(span); + index = position[0] + position[1]; + var highlight = document.createElement('span'); + highlight.classList.add('search-result-highlight'); + highlight.innerHTML = text.substring(position[0], index); + parent.appendChild(highlight); + } + var span = document.createElement('span'); + span.innerHTML = text.substring(index, end); + parent.appendChild(span); + } + } + + jtd.addEvent(searchInput, 'focus', function(){ + setTimeout(update, 0); + }); + + jtd.addEvent(searchInput, 'keyup', function(e){ + switch (e.keyCode) { + case 27: // When esc key is pressed, hide the results and clear the field + searchInput.value = ''; + break; + case 38: // arrow up + case 40: // arrow down + case 13: // enter + e.preventDefault(); + return; + } + update(); + }); + + jtd.addEvent(searchInput, 'keydown', function(e){ + switch (e.keyCode) { + case 38: // arrow up + e.preventDefault(); + var active = document.querySelector('.search-result.active'); + if (active) { + active.classList.remove('active'); + if (active.parentElement.previousSibling) { + var previous = active.parentElement.previousSibling.querySelector('.search-result'); + previous.classList.add('active'); + } + } + return; + case 40: // arrow down + e.preventDefault(); + var active = document.querySelector('.search-result.active'); + if (active) { + if (active.parentElement.nextSibling) { + var next = active.parentElement.nextSibling.querySelector('.search-result'); + active.classList.remove('active'); + next.classList.add('active'); + } + } else { + var next = document.querySelector('.search-result'); + if (next) { + next.classList.add('active'); + } + } + return; + case 13: // enter + e.preventDefault(); + var active = document.querySelector('.search-result.active'); + if (active) { + active.click(); + } else { + var first = document.querySelector('.search-result'); + if (first) { + first.click(); + } + } + return; + } + }); + + jtd.addEvent(document, 'click', function(e){ + if (e.target != searchInput) { + hideSearch(); + } + }); +} + +// Switch theme + +jtd.getTheme = function() { + var cssFileHref = document.querySelector('[rel="stylesheet"]').getAttribute('href'); + return cssFileHref.substring(cssFileHref.lastIndexOf('-') + 1, cssFileHref.length - 4); +} + +jtd.setTheme = function(theme) { + var cssFile = document.querySelector('[rel="stylesheet"]'); + cssFile.setAttribute('href', '/ostree/assets/css/just-the-docs-' + theme + '.css'); +} + +// Scroll site-nav to ensure the link to the current page is visible + +function scrollNav() { + const href = document.location.pathname; + const siteNav = document.getElementById('site-nav'); + const targetLink = siteNav.querySelector('a[href="' + href + '"], a[href="' + href + '/"]'); + if(targetLink){ + const rect = targetLink.getBoundingClientRect(); + siteNav.scrollBy(0, rect.top - 3*rect.height); + } +} + +// Document ready + +jtd.onReady(function(){ + initNav(); + initSearch(); + scrollNav(); +}); + +// Copy button on code + +jtd.onReady(function(){ + + var codeBlocks = document.querySelectorAll('div.highlighter-rouge, div.listingblock > div.content, figure.highlight'); + + // note: the SVG svg-copied and svg-copy is only loaded as a Jekyll include if site.enable_copy_code_button is true; see _includes/icons/icons.html + var svgCopied = ''; + var svgCopy = ''; + + codeBlocks.forEach(codeBlock => { + var copyButton = document.createElement('button'); + var timeout = null; + copyButton.type = 'button'; + copyButton.ariaLabel = 'Copy code to clipboard'; + copyButton.innerHTML = svgCopy; + codeBlock.append(copyButton); + + copyButton.addEventListener('click', function () { + if(timeout === null) { + var code = (codeBlock.querySelector('pre:not(.lineno, .highlight)') || codeBlock.querySelector('code')).innerText; + window.navigator.clipboard.writeText(code); + + copyButton.innerHTML = svgCopied; + + var timeoutSetting = 4000; + + timeout = setTimeout(function () { + copyButton.innerHTML = svgCopy; + timeout = null; + }, timeoutSetting); + } + }); + }); + +}); + +})(window.jtd = window.jtd || {}); + + diff --git a/assets/js/search-data.json b/assets/js/search-data.json new file mode 100644 index 0000000000..ffb06b324f --- /dev/null +++ b/assets/js/search-data.json @@ -0,0 +1,989 @@ +{"0": { + "doc": "Contributing", + "title": "Contributing", + "content": ". | Submitting patches | Commit message style | Running the test suite | Coding style | Contributing Tutorial | Release process | . ", + "url": "/ostree/CONTRIBUTING/", + + "relUrl": "/CONTRIBUTING/" + },"1": { + "doc": "Contributing", + "title": "Submitting patches", + "content": "A majority of current maintainers prefer the GitHub pull request model, and this motivated moving the primary git repository to https://github.com/ostreedev/ostree. However, we do not use the “Merge pull request” button, because we do not like merge commits for one-patch pull requests, among other reasons. See this issue for more information. Instead, we use an instance of Homu, currently known as cgwalters-bot. As a review proceeds, the preferred method is to push fixup! commits. Any commits committed with the --fixup option will have have the word fixup! in its commit title. This is to indicate that this particular commit will be squashed with the commit that was specified in this command, git commit --fixup <commit ref or hash>. Homu knows how to use --autosquash when performing the final merge. See the Git documentation for more information. Alternative methods if you don’t like GitHub (also fully supported): . | Send mail to ostree-list@gnome.org, with the patch attached | Attach them to https://bugzilla.gnome.org/ | . It is likely however once a patch is ready to apply a maintainer will push it to a GitHub PR, and merge via Homu. ", + "url": "/ostree/CONTRIBUTING/#submitting-patches", + + "relUrl": "/CONTRIBUTING/#submitting-patches" + },"2": { + "doc": "Contributing", + "title": "Commit message style", + "content": "Please look at git log and match the commit log style, which is very similar to the Linux kernel. You may use Signed-off-by, but we’re not requiring it. General Commit Message Guidelines: . | Title . | Specify the context or category of the changes e.g. lib for library changes, docs for document changes, bin/<command-name> for command changes, etc. | Begin the title with the first letter of the first word capitalized. | Aim for less than 50 characters, otherwise 72 characters max. | Do not end the title with a period. | Use an imperative tone. | . | Body . | Separate the body with a blank line after the title. | Begin a paragraph with the first letter of the first word capitalized. | Each paragraph should be formatted within 72 characters. | Content should be about what was changed and why this change was made. | If your commit fixes an issue, the commit message should end with Closes: #<number>. | . | . Commit Message example: . <context>: Less than 50 characters for subject title A paragraph of the body should be within 72 characters. This paragraph is also less than 72 characters. For more information see How to Write a Git Commit Message . Editing a Committed Message: . To edit the message from the most recent commit run git commit --amend. To change older commits on the branch use git rebase -i. For a successful rebase have the branch track upstream main. Once the changes have been made and saved, run git push --force origin <branch-name>. ", + "url": "/ostree/CONTRIBUTING/#commit-message-style", + + "relUrl": "/CONTRIBUTING/#commit-message-style" + },"3": { + "doc": "Contributing", + "title": "Running the test suite", + "content": "OSTree uses both make check and supports the Installed Tests model as well (if --enable-installed-tests is provided). ", + "url": "/ostree/CONTRIBUTING/#running-the-test-suite", + + "relUrl": "/CONTRIBUTING/#running-the-test-suite" + },"4": { + "doc": "Contributing", + "title": "Coding style", + "content": "Indentation is GNU. Files should start with the appropriate mode lines. Use GCC __attribute__((cleanup)) wherever possible. If interacting with a third party library, try defining local cleanup macros. Use GError and GCancellable where appropriate. Prefer returning gboolean to signal success/failure, and have output values as parameters. Prefer linear control flow inside functions (aside from standard loops). In other words, avoid “early exits” or use of goto besides goto out;. This is an example of an “early exit”: . static gboolean myfunc (...) { gboolean ret = FALSE; /* some code */ /* some more code */ if (condition) return FALSE; /* some more code */ ret = TRUE; out: return ret; } . If you must shortcut, use: . if (condition) { ret = TRUE; goto out; } . A consequence of this restriction is that you are encouraged to avoid deep nesting of loops or conditionals. Create internal static helper functions, particularly inside loops. For example, rather than: . while (condition) { /* some code */ if (condition) { for (i = 0; i < somevalue; i++) { if (condition) { /* deeply nested code */ } /* more nested code */ } } } . Instead do this: . static gboolean helperfunc (..., GError **error) { if (condition) { /* deeply nested code */ } /* more nested code */ return ret; } while (condition) { /* some code */ if (!condition) continue; for (i = 0; i < somevalue; i++) { if (!helperfunc (..., i, error)) goto out; } } . ", + "url": "/ostree/CONTRIBUTING/#coding-style", + + "relUrl": "/CONTRIBUTING/#coding-style" + },"5": { + "doc": "Contributing", + "title": "Contributing Tutorial", + "content": "For a detailed walk-through on building, modifying, and testing, see this tutorial on how to start contributing to OSTree. ", + "url": "/ostree/CONTRIBUTING/#contributing-tutorial", + + "relUrl": "/CONTRIBUTING/#contributing-tutorial" + },"6": { + "doc": "Contributing", + "title": "Release process", + "content": "Releases can be performed by creating a new release ticket and following the steps in the checklist there. ", + "url": "/ostree/CONTRIBUTING/#release-process", + + "relUrl": "/CONTRIBUTING/#release-process" + },"7": { + "doc": "Historical OSTree README", + "title": "Historical OSTree README", + "content": "This file is outdated, but some of the text here is still useful for historical context. I’m preserving it (explicitly still in the tree) for posterity. ", + "url": "/ostree/README-historical/", + + "relUrl": "/README-historical/" + },"8": { + "doc": "Historical OSTree README", + "title": "Problem statement", + "content": "Hacking on the core operating system is painful - this includes most of GNOME from upower and NetworkManager up to gnome-shell. I want a system that matches these requirements: . | Does not disturb your existing OS | Is not terribly slow to use | Shares your $HOME - you have your data | Allows easy rollback | Ideally allows access to existing apps | . ", + "url": "/ostree/README-historical/#problem-statement", + + "relUrl": "/README-historical/#problem-statement" + },"9": { + "doc": "Historical OSTree README", + "title": "Comparison with existing tools", + "content": ". | Virtualization . Fails on points 2) and 3). Actually qemu-kvm can be pretty fast, but in a lot of cases there is no substitute for actually booting on bare metal; GNOME 3 really needs some hardware GPU acceleration. | Rebuilding distribution packages . Fails on points 1) and 4). Is also just very annoying: dpkg/rpm both want tarballs, which you don’t have since you’re working from git. The suggested “mock/pbuilder” type chroot builds are slow. And even with non-chroot builds there is lots of pointless build wrapping going on. Both dpkg and rpm also are poor at helping you revert back to the original system. All of this can be scripted to be less bad of course - and I have worked on such scripts. But fundamentally you’re still fighting the system, and if you’re hacking on a lowlevel library like say glib, you can easily get yourself to the point where you need a recovery CD - at that point your edit/compile/debug cycle is just too long. | “sudo make install” . Now your system is in an undefined state. You can use e.g. rpm -qV to try to find out what you overwrote, but neither dpkg nor rpm will help clean up any files left over that aren’t shipped by the old package. This is most realistic option for people hacking on system components currently, but ostree will be better. | LXC / containers . Fails on 3), and 4) is questionable. Also shares the annoying part of rebuilding distribution packages. LXC is focused on running multiple server systems at the same time, which isn’t what we want (at least, not right now), and honestly even trying to support that for a graphical desktop would be a lot of tricky work, for example getting two GDM instances not to fight over VT allocations. But some bits of the technology may make sense to use. | jhbuild + distribution packages . The state of the art in GNOME - but can only build non-root things - this means you can’t build NetworkManager, and thus are permanently stuck on whatever the distro provides. | . ", + "url": "/ostree/README-historical/#comparison-with-existing-tools", + + "relUrl": "/README-historical/#comparison-with-existing-tools" + },"10": { + "doc": "Historical OSTree README", + "title": "Who is ostree for?", + "content": "First - operating system developers and testers. I specifically keep a few people in mind - Dan Williams and Eric Anholt, as well as myself obviously. For Eric Anholt, a key use case for him is being able to try out the latest gnome-shell, and combine it with his work on Mesa, and see how it works/performs - while retaining the ability to roll back if one or both breaks. The rollback concept is absolutely key for shipping anything to enthusiasts or knowledable testers. With a system like this, a tester can easily perform a local rollback - something just not well supported by dpkg/rpm. (What about Conary? See below.) . Also, distributing operating system trees (instead of packages) gives us a sane place to perform automated QA before we ship it to testers. We should never be wasting these people’s time. Even better, this system would allow testers to bisect across operating system builds, and do so very efficiently. ", + "url": "/ostree/README-historical/#who-is-ostree-for", + + "relUrl": "/README-historical/#who-is-ostree-for" + },"11": { + "doc": "Historical OSTree README", + "title": "The core idea - chroots", + "content": "chroots are the original lightweight “virtualization”. Let’s use them. So basically, you install a mainstream distribution (say Debian). It has a root filesystem like this: . /usr /etc /home ... Now, what we can do is have a system that installs chroots as a subdirectory of the root, like: . /ostree/gnomeos-3.0-opt-393a4555/{usr,etc,sbin,...} /ostree/gnomeos-3.2-opt-7e9788a2/{usr,etc,sbin,...} . These live in the same root filesystem as your regular distribution (Note though, the root partition should be reasonably sized, or hopefully you’ve used just one big partition). You should be able to boot into one of these roots. Since ostree lives inside a distro created partition, a tricky part here is that we need to know how to interact with the installed distribution’s grub. This is an annoying but tractable problem. First, we install a kernel+initramfs alongside the distribution’s. Then, we have a “trampoline” ostree-init binary which is statically linked, and boot the kernel with init=/ostree/ostree-init. This then takes care of chrooting and running the init binary. An important note here is that we bind mount the real /home. This means you have your data. This also implies we share uid/gid, so /etc/passwd will have to be in sync. Probably what we’ll do is have a script to pull the data from the “host” OS. I’ve decided for now to move /var into /ostree to avoid sharing it with the “host” distribution, because in practice we’re likely to hit incompatibilities. Do note however /etc lives inside the OSTree; it’s presently versioned and readonly like everything else. On a pure OSTree system, the filesystem layout will look like this: . |-- boot |-- home |-- ostree |-- var |-- current -> gnomeos-3.2-opt-7e9788a2 |-- gnomeos-3.0-opt-393a4555 | |-- etc | |-- lib | |-- mnt | |-- proc | |-- run | |-- sbin | |-- srv | |-- sys | `-- usr | `-- gnomeos-3.2-opt-7e9788a2 |-- etc |-- lib |-- mnt |-- proc |-- run |-- sbin |-- srv |-- sys | `-- usr |-- root . ", + "url": "/ostree/README-historical/#the-core-idea---chroots", + + "relUrl": "/README-historical/#the-core-idea---chroots" + },"12": { + "doc": "Historical OSTree README", + "title": "Making this efficient", + "content": "One of the first things you’ll probably ask is “but won’t that use a lot of disk space”? Indeed, it will, if you just unpack a set of RPMs or .debs into each root. Besides chroots, there’s another old Unix idea we can take advantage of - hard links. These allow sharing the underlying data of a file, with the tradeoff that changing any one file will change all names that point to it. This mutability means that we have to either: . | Make sure everything touching the operating system breaks hard links This is probably tractable over a long period of time, but if anything has a bug, then it corrupts the file effectively. | Make the core OS read-only, with a well-defined mechanism for mutating under the control of ostree. | . I chose 2. ", + "url": "/ostree/README-historical/#making-this-efficient", + + "relUrl": "/README-historical/#making-this-efficient" + },"13": { + "doc": "Historical OSTree README", + "title": "A userspace content-addressed versioning filesystem", + "content": "At its very core, that’s what ostree is. Just like git. If you understand git, you know it’s not like other revision control systems. git is effectively a specialized, userspace filesystem, and that is a very powerful idea. At the core of git is the idea of “content-addressed objects”. For background on this, see http://book.git-scm.com/7_how_git_stores_objects.html . Why not just use git? Basically because git is designed mainly for source trees - it goes to effort to be sure it’s compressing text for example, under the assumption that you have a lot of text. Its handling of binaries is very generic and unoptimized. In contrast, ostree is explicitly designed for binaries, and in particular one type of binary - ELF executables (or it will be once we start using bsdiff). Another big difference versus git is that ostree uses hard links between “checkouts” and the repository. This means each checkout uses almost no additional space, and is extremely fast to check out. We can do this because again each checkout is designed to be read-only. So we mentioned above there are: . /ostree/gnomeos-3.2-opt-7e9788a2 /ostree/gnomeos-3.2-opt-393a4555 . There is also a “repository” that looks like this: . /ostree/repo/objects/17/a95e8ca0ba655b09cb68d7288342588e867ee0.file /ostree/repo/objects/17/68625e7ff5a8db77904c77489dc6f07d4afdba.meta /ostree/repo/objects/17/cc01589dd8540d85c0f93f52b708500dbaa5a9.file /ostree/repo/objects/30 /ostree/repo/objects/30/6359b3ca7684358a3988afd005013f13c0c533.meta /ostree/repo/objects/30/8f3c03010cedd930b1db756ce659c064f0cd7f.meta /ostree/repo/objects/30/8cf0fd8e63dfff6a5f00ba5a48f3b92fb52de7.file /ostree/repo/objects/30/6cad7f027d69a46bb376044434bbf28d63e88d.file . Each object is either metadata (like a commit or tree), or a hard link to a regular file. Note that also unlike git, the checksum here includes metadata such as uid, gid, permissions, and extended attributes. (It does not include file access times, since those shouldn’t matter for the OS) . This is another important component to allowing the hardlinks. We wouldn’t want say all empty files to be shared necessarily. (Though maybe this is wrong, and since the OS is readonly, we can make all files owned by root without loss of generality). However this tradeoff means that we probably need a second index by content, so we don’t have to redownload the entire OS if permissions change =) . ", + "url": "/ostree/README-historical/#a-userspace-content-addressed-versioning-filesystem", + + "relUrl": "/README-historical/#a-userspace-content-addressed-versioning-filesystem" + },"14": { + "doc": "Historical OSTree README", + "title": "Atomic upgrades, rollback", + "content": "OSTree is designed to atomically swap operating systems - such that during an upgrade and reboot process, you either get the full new system, or the old one. There is no “Please don’t turn off your computer”. We do this by simply using a symbolic link like: . /ostree/current -> /ostree/gnomeos-3.4-opt-e3b0c4429 . Where gnomeos-e3b0c4429 has the full regular filesystem tree with usr/ etc/ directories as above. To upgrade or rollback (there is no difference internally), we simply check out a new tree into gnomeos-b90ae4763 for example, then swap the “current” symbolic link, then remove the old tree. But does this mean you have to reboot for OS upgrades? Very likely, yes - and this is no different from RPM/deb or whatever. They just typically lie to you about it =) . A typical model with RPM/deb is to unpack the new files, then use some IPC mechanism (SIGHUP, a control binary like /usr/sbin/apachectl) to signal the running process to reload. There are multiple problems with this - one is that in the new state, daemon A may depend on the updated configuration in daemon B. This may not be particularly common in default configurations, but it’s highly likely that that some deployments will have e.g. apache talking to a local MySQL instance. So you really want to do is only apply the updated configuration when all the files are in place; not after each RPM or .deb is installed. What’s even harder is the massive set of race conditions that are possible while RPM/deb are in the process of upgrading. Cron jobs are very likely to hit this. If we want the ability to apply updates to a live system, we could first pause execution of non-upgrade userspace tasks. This could be done via SIGSTOP for example. Then, we can swap around the filesystem tree, and then finally attempt to apply updates via SIGHUP, and if possible, restart processes. ", + "url": "/ostree/README-historical/#atomic-upgrades-rollback", + + "relUrl": "/README-historical/#atomic-upgrades-rollback" + },"15": { + "doc": "Historical OSTree README", + "title": "Configuration Management", + "content": "By now if you’ve thought about this problem domain before, you’re wondering about configuration management. In other words, if the OS is read only, how do I edit /etc/sudoers? . Well, have you ever been a system administrator on a zypper/yum system, done an RPM update, which then drops .rpmnew files in your /etc/ that you have to go and hunt for with “find” or something, and said to yourself, “Wow, this system is awesome!!!” ? Right, that’s what I thought. Configuration (and systems) management is a tricky problem, and I certainly don’t have a magic bullet. However, one large conceptual improvement I think is defaulting to “rebase” versus “merge”. This means that we won’t permit direct modification of /etc - instead, you HAVE to write a script which accomplishes your goals. To generate a tree, we check out a new copy, then run your script on top. If the script fails, we can roll back the update, or drop to a shell if interactive. However, we also need to consider cases where the administrator modifies state indirectly by a program. Think “adduser” for example. Possible approaches: . | Patch all of these programs to know how to write to the writable location, instead of the R/O bind mount overlay. | Move the data to /var | . ", + "url": "/ostree/README-historical/#configuration-management", + + "relUrl": "/README-historical/#configuration-management" + },"16": { + "doc": "Historical OSTree README", + "title": "What about “packages”?", + "content": "There are several complex and separate issues hiding in this seemingly simple question. I think OSTree always makes sense to use as a core operating system builder and updater. By “core” here I mean the parts that aren’t removable. Debian has Essential: yes, any other distribution has this too implicitly in the set of dependencies for their updater tool. Now, let me just say I will absolutely support using something like apt/yum/zypper (and consequently deb/rpm) on top of OSTree. This isn’t trivial, but there aren’t any conceptual issues. Concretely for example, RPM or .deb might make sense as a delivery vehicle for third party OS extensions. A canoncial example is the NVidia graphics driver. If one is using OSTree to build an operating system, then there has to be some API for applications. And that demands its own targeted solution - something like an evolved glick (zeroinstall is also similar). Current package systems are totally broken for application deployment though; for example, they will remove files away from under running applications on update. And we clearly need the ability to install and upgrade applications without rebooting the OS. ", + "url": "/ostree/README-historical/#what-about-packages", + + "relUrl": "/README-historical/#what-about-packages" + },"17": { + "doc": "Historical OSTree README", + "title": "Details of RPM installation", + "content": "We should be able to install LSB rpms. This implies providing “rpm”. The tricky part here is since the OS itself is not assembled via RPMs, we need to fake up a database of “provides” as if we were. Even harder would be maintaining binary compatibilty with any arbitrary %post scripts that may be run. ", + "url": "/ostree/README-historical/#details-of-rpm-installation", + + "relUrl": "/README-historical/#details-of-rpm-installation" + },"18": { + "doc": "Historical OSTree README", + "title": "What about BTRFS? Doesn’t it solve everything?", + "content": "In short, BTRFS is not a magic bullet, but yes - it helps significantly. The obvious thing to do is layer BTRFS under dpkg/rpm, and have a separate subvolume for /home so rollbacks don’t lose your data. See e.g. http://fedoraproject.org/wiki/Features/SystemRollbackWithBtrfs . As a general rule an issue with the BTRFS is that it can’t roll back just changes to things installed by RPM (i.e. what’s in rpm -qal). For example, it’s possible to e.g. run yum update, then edit something in /etc, reboot and notice things are broken, then roll back and have silently lost your changes to /etc. Another example is adding a new binary in /usr/local. You could say, “OK, we’ll use subvolumes for those!”. But then what about /var (and your VM images that live in /var/lib/libvirt ?) . Finally, probably the biggest disadvantage of the rpm/dpkg + BTRFS approach is it doesn’t solve the race conditions that happen when unpacking packages into the live system. This problem is really important to me. Note though ostree can definitely take advantage of BTRFS features! In particular, we could use “reflink” http://lwn.net/Articles/331808/ instead of hard links, and avoid having the object store corrupted if somehow the files are modified directly. ", + "url": "/ostree/README-historical/#what-about-btrfs--doesnt-it-solve-everything", + + "relUrl": "/README-historical/#what-about-btrfs--doesnt-it-solve-everything" + },"19": { + "doc": "Historical OSTree README", + "title": "Other systems", + "content": "I’ve spent a long time thinking about this problem, and here are some of the other possible solutions out there I looked at, and why I didn’t use them: . | Git: http://git-scm.com/ . Really awesome, and the core inspiration here. But like I mentioned above, not at all designed for binaries - we can make different tradeoffs. | bup: https://github.com/apenwarr/bup . bup is cool. But it shares the negative tradeoffs with git, though it does add positives of its own. It also inspired me. | git-annex: http://git-annex.branchable.com/git-annex/ . Looks interesting; I think this will share the same negative tradeoffs with git as far as using it for an OS goes. | schroot: http://www.debian-administration.org/articles/566 . Like LXC/containers, but just using a chroot. | NixOS: http://nixos.org/ . The NixOS people have a lot of really good ideas, and they’ve definitely thought about the problem space. However, their approach of checksumming all inputs to a package is pretty wacky. I don’t see the point, and moreover it uses gobs of disk space. | Conary: http://wiki.rpath.com/wiki/Conary:Updates_and_Rollbacks . If rpm/dpkg are like CVS, Conary is closer to Subversion. It’s not bad, but ostree is better than it for the exact same reasons git is better than Subversion. | BTRFS: http://en.wikipedia.org/wiki/Btrfs . See above. | Solaris IPS: http://hub.opensolaris.org/bin/view/Project+pkg/ . Rollback is ZFS level, so I think this shares the same tradeoffs as BTRFS+RPM/deb. They probably have some vertical integration though which definitely helps. Obviously we can’t use ZFS. | Jhbuild: https://live.gnome.org/Jhbuild . What we’ve been using in GNOME, and has the essential property of allowing you to “fall back” to a stable system. But ostree will blow it out of the water. | . ", + "url": "/ostree/README-historical/#other-systems", + + "relUrl": "/README-historical/#other-systems" + },"20": { + "doc": "Historical OSTree README", + "title": "Development", + "content": ". | OSTree wiki page: https://live.gnome.org/OSTree . | ostbuild wiki page: https://live.gnome.org/OSTree/Ostbuild . | Git repository: http://git.gnome.org/browse/ostree/ . | Deploying OSTree in the Gnome servers: https://bugzilla.gnome.org/show_bug.cgi?id=669772 . | . ", + "url": "/ostree/README-historical/#development", + + "relUrl": "/README-historical/#development" + },"21": { + "doc": "Adapting existing mainstream distributions", + "title": "Adapting existing mainstream distributions", + "content": ". | System layout | Booting and initramfs technology | System users and groups . | Static users and groups | sysusers.d | . | Adapting existing package managers | . ", + "url": "/ostree/adapting-existing/", + + "relUrl": "/adapting-existing/" + },"22": { + "doc": "Adapting existing mainstream distributions", + "title": "System layout", + "content": "First, OSTree encourages systems to implement UsrMove This is simply to avoid the need for more bind mounts. By default OSTree’s dracut hook creates a read-only bind mount over /usr; you can of course generate individual bind-mounts for /bin, all the /lib variants, etc. So it is not intended to be a hard requirement. Remember, because by default the system is booted into a chroot equivalent, there has to be some way to refer to the actual physical root filesystem. Therefore, your operating system tree should contain an empty /sysroot 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 /ostree which points to /sysroot/ostree, 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. Because OSTree only preserves /var 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 Filesystem Hierarchy Standard. Your operating system may of course choose not to support some of these such as /usr/local, but following is the recommended set: . | /home → /var/home | /opt → /var/opt | /srv → /var/srv | /root → /var/roothome | /usr/local → /var/usrlocal | /mnt → /var/mnt | /tmp → /sysroot/tmp | . Furthermore, since /var is empty by default, your operating system will need to dynamically create the targets of these at boot. A good way to do this is using systemd-tmpfiles, if your OS uses systemd. For example: . 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 - . However, as of OSTree 2023.9 there is support for a root.transient model, which can increase compatibility in some scenarios. For more information, see man ostree-prepare-root.conf. Particularly note here the double indirection of /home. By default, each deployment will share the global toplevel /home directory on the physical root filesystem. It is then up to higher levels of management tools to keep /etc/passwd or equivalent synchronized between operating systems. Each deployment can easily be reconfigured to have its own home directory set simply by making /var/home a real directory. ", + "url": "/ostree/adapting-existing/#system-layout", + + "relUrl": "/adapting-existing/#system-layout" + },"23": { + "doc": "Adapting existing mainstream distributions", + "title": "Booting and initramfs technology", + "content": "OSTree comes with optional dracut+systemd integration code which follows this logic: . | Parse the ostree= kernel command line argument in the initramfs | Set up a read-only bind mount on /usr | Bind mount the deployment’s /sysroot to the physical / | Use mount(MS_MOVE) to make the deployment root appear to be the root filesystem | . After these steps, systemd switches root. 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 src/switchroot as a reference. Patches to support other initramfs technologies and init systems, if sufficiently clean, will likely be accepted upstream. A further specific note regarding sysvinit: OSTree used to support recording device files such as the /dev/initctl FIFO, but no longer does. It’s recommended to just patch your initramfs to create this at boot. ", + "url": "/ostree/adapting-existing/#booting-and-initramfs-technology", + + "relUrl": "/adapting-existing/#booting-and-initramfs-technology" + },"24": { + "doc": "Adapting existing mainstream distributions", + "title": "System users and groups", + "content": "Unlike traditional package systems, OSTree trees contain numeric uid and gids (the same is true of e.g. OCI). Furthermore, OSTree does not have a %post type mechanism where useradd 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 /etc/passwd. The core problem is that if you add a user to the system for a daemon, the OSTree upgrade process for /etc will simply notice that because /etc/passwd differs from the previous default, it will keep the modified config file, and your new OS user will not be visible. First, consider using systemd DynamicUser=yes where applicable. This entirely avoids problems with static allocations. Static users and groups . For users which must be allocated statically (for example, they are used by setuid executables in /usr/bin, there are two primary wants to handle this. The nss-altfiles was created to pair with image-based update systems like OSTree, and is used by many operating systems and distributions today. More recently, nss-systemd gained support for statically allocated users and groups in a JSON format stored in /usr/lib/userdb. sysusers.d . Some users and groups can be assigned dynamically via sysusers.d. This means users and groups are maintained per-machine and may drift (unless statically assigned in sysusers). But this model is suitable for users and groups which must always be present, but do not have file content in the image. ", + "url": "/ostree/adapting-existing/#system-users-and-groups", + + "relUrl": "/adapting-existing/#system-users-and-groups" + },"25": { + "doc": "Adapting existing mainstream distributions", + "title": "Adapting existing package managers", + "content": "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 /. This section will use examples from both dpkg and rpm as the author has familiarity with both; but the abstract concepts should apply to most traditional package managers. 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. Many package managers store their state in /var; but since in the OSTree model that directory is shared between independent versions, the package database must first be found in the per-deployment /usr 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 /var location if the one in /usr is not found. 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. 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 layering the composed filesystem tree of these new packages on top. A command like this: . ostree commit -b osname/releasename/description --tree=ref=$osname/$releasename/$description --tree=dir=/var/tmp/newpackages.13A8D0/ . will create a new commit in the $osname/$releasename/$description branch. The OSTree SHA256 checksum of all the files in /var/tmp/newpackages.13A8D0/ 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. Then to actually deploy this tree for the next boot: ostree admin deploy $osname/$releasename/$description . This is essentially what rpm-ostree does to support its package layering model. ", + "url": "/ostree/adapting-existing/#adapting-existing-package-managers", + + "relUrl": "/adapting-existing/#adapting-existing-package-managers" + },"26": { + "doc": "Atomic Rollbacks", + "title": "Atomic Rollbacks", + "content": ". | Automatic rollbacks | Manual rollbacks | Rollbacks | Alternate rollback techniques | . ", + "url": "/ostree/atomic-rollbacks/", + + "relUrl": "/atomic-rollbacks/" + },"27": { + "doc": "Atomic Rollbacks", + "title": "Automatic rollbacks", + "content": "See greenboot for information on automatic rollbacks and how to integrate without your bootloader. ", + "url": "/ostree/atomic-rollbacks/#automatic-rollbacks", + + "relUrl": "/atomic-rollbacks/#automatic-rollbacks" + },"28": { + "doc": "Atomic Rollbacks", + "title": "Manual rollbacks", + "content": "Ostree writes bootloader entries that are interpreted by the bootloader. To manually rollback, for bootloaders such as GRUB and syslinux that have an interactive UI, it is possible to select a previous boot entry. In the case of an Android bootloader, a slot switch may be triggererd using an AB switching tool. This may be useful for testing purposes. ", + "url": "/ostree/atomic-rollbacks/#manual-rollbacks", + + "relUrl": "/atomic-rollbacks/#manual-rollbacks" + },"29": { + "doc": "Atomic Rollbacks", + "title": "Rollbacks", + "content": "+------------------------------------------------+ +------------------+ | | | | | | | (ostree:0) latest (multi-user.target) | | | Bootloader |--->+ root | | | | (ostree:1) latest - 1 (multi-user.target) | | | | | +------------------+ | +------------------------------------------------+ . Bootloaders have multiple boot entries to choose from after upgrade. On rollback, the bootloader will boot the “latest - 1” version, rather than the latest version of the OS. ", + "url": "/ostree/atomic-rollbacks/#rollbacks", + + "relUrl": "/atomic-rollbacks/#rollbacks" + },"30": { + "doc": "Atomic Rollbacks", + "title": "Alternate rollback techniques", + "content": "Below is an alternate technique to traditional AB switching that can be used. On rollback, an alternative boot target is used, rather than booting as default.target. +------------------------------------------------+ +------------------+ | | | | | | | (ostree:0) latest (multi-user.target) | | | Bootloader |--->+ root | | | | (ostree:1) latest - 1 (rescue.target) | | | | | +------------------+ | +------------------------------------------------+ . In this case, instead of rolling back to an older version, we also boot into an alternate systemd boot target. Here we will describe how you can put togther an alternate systemd boot target, using the built-in rescue.target as an example. Below is a rescue.service file, it essentially executes systemd-sulogin-shell rescue when this service is activated. rescue.service: . # SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Rescue Shell Documentation=man:sulogin(8) DefaultDependencies=no Conflicts=shutdown.target After=sysinit.target plymouth-start.service Before=shutdown.target [Service] Environment=HOME=/root WorkingDirectory=-/root ExecStartPre=-/usr/bin/plymouth --wait quit ExecStart=-/usr/lib/systemd/systemd-sulogin-shell rescue Type=idle StandardInput=tty-force StandardOutput=inherit StandardError=inherit KillMode=process IgnoreSIGPIPE=no SendSIGHUP=yes . Below is a rescue.target file, it is reached once rescue.service is complete. rescue.target: . # SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Rescue Mode Documentation=man:systemd.special(7) Requires=sysinit.target rescue.service After=sysinit.target rescue.service AllowIsolate=yes . This is a simple bash script, it checks whether ostree admin status -D is not-default and if it is, it notifies systemd to alternatively boot into rescue.target. In the happy path, when we have booted the latest version ostree admin status -D would output default. ostree-rollback-to-rescue: . #!/usr/bin/bash set -euo pipefail if [ \"$(ostree admin status -D)\" = \"not-default\" ]; then exec systemctl --no-block isolate rescue.target fi . This is a systemd service file that runs ostree-rollback-to-rescue early in the boot sequence, it is essential that this service is run early to ensure we don’t execute a full boot sequence, hence options DefaultDependencies=no and Before= are used. ostree-rollback-to-rescue.service . [Unit] Description=OSTree rollback to rescue DefaultDependencies=no OnFailure=emergency.target OnFailureJobMode=replace-irreversibly After=initrd-root-fs.target initrd-fs.target initrd.target boot.mount Before=cryptsetup.target integritysetup.target remote-fs.target slices.target swap.target veritysetup.target [Service] Type=oneshot ExecStart=/usr/sbin/ostree-rollback-to-rescue [Install] WantedBy=sysinit.target . ", + "url": "/ostree/atomic-rollbacks/#alternate-rollback-techniques", + + "relUrl": "/atomic-rollbacks/#alternate-rollback-techniques" + },"31": { + "doc": "Atomic Upgrades", + "title": "Atomic Upgrades", + "content": ". | You can turn off the power anytime you want… | Simple upgrades via HTTP | Upgrades via external tools (e.g. package managers) | Assembling a new deployment directory | Atomically swapping boot configuration | The bootversion | The /ostree/boot directory | . ", + "url": "/ostree/atomic-upgrades/", + + "relUrl": "/atomic-upgrades/" + },"32": { + "doc": "Atomic Upgrades", + "title": "You can turn off the power anytime you want…", + "content": "OSTree is designed to implement fully atomic and safe upgrades; more generally, atomic transitions between lists of bootable deployments. If the system crashes or you pull the power, you will have either the old system, or the new one. ", + "url": "/ostree/atomic-upgrades/#you-can-turn-off-the-power-anytime-you-want", + + "relUrl": "/atomic-upgrades/#you-can-turn-off-the-power-anytime-you-want" + },"33": { + "doc": "Atomic Upgrades", + "title": "Simple upgrades via HTTP", + "content": "First, the most basic model OSTree supports is one where it replicates pre-generated filesystem trees from a server over HTTP, tracking exactly one ref, which is stored in the .origin file for the deployment. The command ostree admin upgrade implements this. To begin a simple upgrade, OSTree fetches the contents of the ref from the remote server. Suppose we’re tracking a ref named exampleos/buildmain/x86_64-runtime. OSTree fetches the URL http://example.com/repo/refs/heads/exampleos/buildmain/x86_64-runtime, which contains a SHA256 checksum. This determines the tree to deploy, and /etc will be merged from currently booted tree. If we do not have this commit, then we perform a pull process. At present (without static deltas), this involves quite simply just fetching each individual object that we do not have, asynchronously. Put in other words, we only download changed files (zlib-compressed). Each object has its checksum validated and is stored in /ostree/repo/objects/. Once the pull is complete, we have downloaded all the objects that we need to perform a deployment. ", + "url": "/ostree/atomic-upgrades/#simple-upgrades-via-http", + + "relUrl": "/atomic-upgrades/#simple-upgrades-via-http" + },"34": { + "doc": "Atomic Upgrades", + "title": "Upgrades via external tools (e.g. package managers)", + "content": "As mentioned in the introduction, OSTree is also designed to allow a model where filesystem trees are computed on the client. It is completely agnostic as to how those trees are generated; they could be computed with traditional packages, packages with post-deployment scripts on top, or built by developers directly from revision control locally, etc. At a practical level, most package managers today (dpkg and rpm) operate “live” on the currently booted filesystem. The way they could work with OSTree is to, instead, take the list of installed packages in the currently booted tree, and compute a new filesystem from that. A later chapter describes in more details how this could work: Adapting Existing Systems. For the purposes of this section, let’s assume that we have a newly generated filesystem tree stored in the repo (which shares storage with the existing booted tree). We can then move on to checking it back out of the repo into a deployment. ", + "url": "/ostree/atomic-upgrades/#upgrades-via-external-tools-eg-package-managers", + + "relUrl": "/atomic-upgrades/#upgrades-via-external-tools-eg-package-managers" + },"35": { + "doc": "Atomic Upgrades", + "title": "Assembling a new deployment directory", + "content": "Given a commit to deploy, OSTree first allocates a directory for it. This is of the form /boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf. The $serial is normally 0, but if a given commit is deployed more than once, it will be incremented. This is supported because the previous deployment may have configuration in /etc that we do not want to use or overwrite. Now that we have a deployment directory, a 3-way merge is performed between the (by default) currently booted deployment’s /etc, its default configuration, and the new deployment (based on its /usr/etc). How it works is: . | Files in the currently booted deployment’s /etc which were modified from the default /usr/etc (of the same deployment) are retained. | Files in the currently booted deployment’s /etc which were not modified from the default /usr/etc (of the same deployment) are upgraded to the new defaults from the new deployment’s /usr/etc. | . Roughly, this means that as soon as you modify or add a file in /etc, this file will be propagated forever as is (though there is a corner-case, where if your modification eventually exactly matches a future default file, then the file will go back to following future default updates from that point on). You can use ostree admin config-diff to see the differences between your booted deployment’s /etc and the OSTree defaults. A command like diff {/usr,}/etc will additional print line-level differences. ", + "url": "/ostree/atomic-upgrades/#assembling-a-new-deployment-directory", + + "relUrl": "/atomic-upgrades/#assembling-a-new-deployment-directory" + },"36": { + "doc": "Atomic Upgrades", + "title": "Atomically swapping boot configuration", + "content": "At this point, a new deployment directory has been created as a hardlink farm; the running system is untouched, and the bootloader configuration is untouched. We want to add this deployment to the “deployment list”. To support a more general case, OSTree supports atomic transitioning between arbitrary sets of deployments, with the restriction that the currently booted deployment must always be in the new set. In the normal case, we have exactly one deployment, which is the booted one, and we want to add the new deployment to the list. A more complex command might allow creating 100 deployments as part of one atomic transaction, so that one can set up an automated system to bisect across them. ", + "url": "/ostree/atomic-upgrades/#atomically-swapping-boot-configuration", + + "relUrl": "/atomic-upgrades/#atomically-swapping-boot-configuration" + },"37": { + "doc": "Atomic Upgrades", + "title": "The bootversion", + "content": "OSTree allows swapping between boot configurations by implementing the “swapped directory pattern” in /boot. This means it is a symbolic link to one of two directories /ostree/boot.[0|1]. To swap the contents atomically, if the current version is 0, we create /ostree/boot.1, populate it with the new contents, then atomically swap the symbolic link. Finally, the old contents can be garbage collected at any point. ", + "url": "/ostree/atomic-upgrades/#the-bootversion", + + "relUrl": "/atomic-upgrades/#the-bootversion" + },"38": { + "doc": "Atomic Upgrades", + "title": "The /ostree/boot directory", + "content": "However, we want to optimize for the case where the set of kernel/initramfs/devicetree sets is the same between both the old and new deployment lists. This happens when doing an upgrade that does not include the kernel; think of a simple translation update. OSTree optimizes for this case because on some systems /boot may be on a separate medium such as flash storage not optimized for significant amounts of write traffic. Related to this, modern OSTree has support for having /boot be a read-only mount by default - it will automatically remount read-write just for the portion of time necessary to update the bootloader configuration. To implement this, OSTree also maintains the directory /ostree/boot.$bootversion, which is a set of symbolic links to the deployment directories. The $bootversion here must match the version of /boot. However, in order to allow atomic transitions of this directory, this is also a swapped directory, so just like /boot, it has a version of 0 or 1 appended. Each bootloader entry has a special ostree= argument which refers to one of these symbolic links. This is parsed at runtime in the initramfs. ", + "url": "/ostree/atomic-upgrades/#the-ostreeboot-directory", + + "relUrl": "/atomic-upgrades/#the-ostreeboot-directory" + },"39": { + "doc": "Handling access to authenticated remote repositories", + "title": "Handling access to authenticated remote repositories", + "content": ". | Using mutual TLS | Using basic authentication | Using cookies | . There is no default concept of an “ostree server”; ostree expects to talk to a generic webserver, so any tool and technique applicable for generic HTTP can also apply to fetching content via OSTree’s builtin HTTP client. ", + "url": "/ostree/authenticated-repos/", + + "relUrl": "/authenticated-repos/" + },"40": { + "doc": "Handling access to authenticated remote repositories", + "title": "Using mutual TLS", + "content": "The tls-client-cert-path and tls-client-key-path expose the underlying HTTP code for mutual TLS. Each device can be provisioned with a secret key which grants it access to the webserver. ", + "url": "/ostree/authenticated-repos/#using-mutual-tls", + + "relUrl": "/authenticated-repos/#using-mutual-tls" + },"41": { + "doc": "Handling access to authenticated remote repositories", + "title": "Using basic authentication", + "content": "The client supports HTTP basic authentication, but this has well-known management drawbacks. ", + "url": "/ostree/authenticated-repos/#using-basic-authentication", + + "relUrl": "/authenticated-repos/#using-basic-authentication" + },"42": { + "doc": "Handling access to authenticated remote repositories", + "title": "Using cookies", + "content": "Since this pull request ostree supports adding cookies to a remote configuration. This can be used with e.g. Amazon CloudFront. ", + "url": "/ostree/authenticated-repos/#using-cookies", + + "relUrl": "/authenticated-repos/#using-cookies" + },"43": { + "doc": "Bootloaders", + "title": "Bootloaders", + "content": ". | OSTree and bootloaders | OSTree and grub | OSTree and aboot | GRUB and os-prober | Anaconda | bootupd | . ", + "url": "/ostree/bootloaders/", + + "relUrl": "/bootloaders/" + },"44": { + "doc": "Bootloaders", + "title": "OSTree and bootloaders", + "content": "The intended design of OSTree is that it just writes new files into /boot/loader/entries. There is a legacy GRUB script (shipped on Fedora as ostree-grub2) that is intended only for the cases where the system GRUB does not support the blscfg verb. In the happy path then, the flow of an OS update is just: . | ostree writes a new set of files in /boot/loader/entries (during ostree-finalize-staged.service on system shutdown) | On system start, GRUB reads those files | . And that’s it. ", + "url": "/ostree/bootloaders/#ostree-and-bootloaders", + + "relUrl": "/bootloaders/#ostree-and-bootloaders" + },"45": { + "doc": "Bootloaders", + "title": "OSTree and grub", + "content": "For historical reasons, OSTree defaults to detecting the bootloader; if some GRUB files are present then OSTree will default to executing grub2-mkconfig. ", + "url": "/ostree/bootloaders/#ostree-and-grub", + + "relUrl": "/bootloaders/#ostree-and-grub" + },"46": { + "doc": "Bootloaders", + "title": "OSTree and aboot", + "content": "The Android bootloader is another bootloader than may be used with ostree. It still uses the files in /boot/loader/entries as metadata, but the boootloader does not read these files. Android bootloaders package their kernel+initramfs+cmdline+dtb in a signed binary blob called an Android Boot Image. This binary blob then is written to either partition boot_a or boot_b depending on which slot is suitable. Android bootloaders by design inject kargs into the cmdline, some patches may be required in the Android bootloader implementation to ensure that the firmware does not switch between system_a and system_b partitions by populating a root= karg, or that a ro karg that is incompatible with ostree is not inserted. Conversly leaving the androidboot.slot_suffix= karg injecting functionality is required but this is commonplace for any Android Bootloader that does AB updates. We have two accompanying scripts that work with this type of environment: . aboot-update is used to generate Android Boot Images to be delivered to the client. aboot-deploy reads what the current slot is according to the androidboot.slot_suffix= karg, writes to the alternate boot_a or boot_b slot and sets a symlink either /ostree/root.a or /ostree/root.b so that it is known which userspace directory to boot into based on the androidboot.slot_suffix= karg, on subsequent boots. +-----------------------------+ +---------------------------------+ | +------------------+ | | firmware appends: | | | +--->+ boot_a partition +--->+ | androidboot.slot_suffix=_a | | /ostree/root.a | | +------------------+ | | or | system_a partition | | +------------------+ | | androidboot.slot_suffix=_b | | /ostree/root.b | +--->+ boot_b partition +--->+ | to cmdline | | | | +------------------+ | +-----------------------------+ +---------------------------------+ . ", + "url": "/ostree/bootloaders/#ostree-and-aboot", + + "relUrl": "/bootloaders/#ostree-and-aboot" + },"47": { + "doc": "Bootloaders", + "title": "GRUB and os-prober", + "content": "A specific component of GRUB that can significantly impede the reliability of OS updates is the os-prober aspect, which scans all system block devices. If one doesn’t care about dual booting, avoiding this is a good idea. ", + "url": "/ostree/bootloaders/#grub-and-os-prober", + + "relUrl": "/bootloaders/#grub-and-os-prober" + },"48": { + "doc": "Bootloaders", + "title": "Anaconda", + "content": "Until very recently, the Anaconda project only supported setting up the bootloader (e.g. GRUB) on its own, which requires grub2-mkconfig etc. As of recently, Anaconda now supports bootupd. ", + "url": "/ostree/bootloaders/#anaconda", + + "relUrl": "/bootloaders/#anaconda" + },"49": { + "doc": "Bootloaders", + "title": "bootupd", + "content": "As of recently, the bootupd project ships static grub configs and in this case, the sysroot.bootloader should be set to none (except on s390x). And assuming that the system grub has the blscfg support, which it does on Fedora derivatives per above. ", + "url": "/ostree/bootloaders/#bootupd", + + "relUrl": "/bootloaders/#bootupd" + },"50": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Writing a buildsystem and managing repositories", + "content": ". | Build vs buy | Initializing | Writing your own OSTree buildsystem | Constructing trees from unions | Migrating content between repositories | More sophisticated repository management | . OSTree is not a package system. It does not directly support building source code. Rather, it is a tool for transporting and managing content, along with package-system independent aspects like bootloader management for updates. We’ll assume here that we’re planning to generate commits on a build server, then have client systems replicate it. Doing client-side assembly is also possible of course, but this discussion will focus primarily on server-side concerns. ", + "url": "/ostree/buildsystem-and-repos/", + + "relUrl": "/buildsystem-and-repos/" + },"51": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Build vs buy", + "content": "Therefore, you need to either pick an existing tool for writing content into an OSTree repository, or write your own. An example tool is rpm-ostree - it takes as input RPMs, and commits them (currently oriented for server-side, but aiming to do client-side too). ", + "url": "/ostree/buildsystem-and-repos/#build-vs-buy", + + "relUrl": "/buildsystem-and-repos/#build-vs-buy" + },"52": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Initializing", + "content": "For this initial discussion, we’re assuming you have a single archive repository: . mkdir repo ostree --repo=repo init --mode=archive . You can export this via a static webserver, and configure clients to pull from it. ", + "url": "/ostree/buildsystem-and-repos/#initializing", + + "relUrl": "/buildsystem-and-repos/#initializing" + },"53": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Writing your own OSTree buildsystem", + "content": "There exist many, many systems that basically follow this pattern: . $pkg --installroot=/path/to/tmpdir install foo bar baz $imagesystem commit --root=/path/to/tmpdir . For various values of $pkg such as yum, apt-get, etc., and values of $imagesystem could be simple tarballs, Amazon Machine Images, ISOs, etc. Now obviously in this document, we’re going to talk about the situation where $imagesystem is OSTree. The general idea with OSTree is that wherever you might store a series of tarballs for applications or OS images, OSTree is likely going to be better. For example, it supports GPG signatures, binary deltas, writing bootloader configuration, etc. OSTree does not include a package/component build system simply because there already exist plenty of good ones - rather, it is intended to provide an infrastructure layer. The above mentioned rpm-ostree compose tree chooses RPM as the value of $pkg - so binaries are built as RPMs, then committed as a whole into an OSTree commit. But let’s discuss building our own. If you’re just experimenting, it’s quite easy to start with the command line. We’ll assume for this purpose that you have a build process that outputs a directory tree - we’ll call this tool $pkginstallroot (which could be yum --installroot or debootstrap, etc.). Your initial prototype is going to look like: . $pkginstallroot /path/to/tmpdir ostree --repo=repo commit -s 'build' -b exampleos/x86_64/standard --tree=dir=/path/to/tmpdir . Alternatively, if your build system can generate a tarball, you can commit that tarball into OSTree. For example, OpenEmbedded can output a tarball, and one can commit it via: . ostree commit -s 'build' -b exampleos/x86_64/standard --tree=tar=myos.tar . ", + "url": "/ostree/buildsystem-and-repos/#writing-your-own-ostree-buildsystem", + + "relUrl": "/buildsystem-and-repos/#writing-your-own-ostree-buildsystem" + },"54": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Constructing trees from unions", + "content": "The above is a very simplistic model, and you will quickly notice that it’s slow. This is because OSTree has to re-checksum and recompress the content each time it’s committed. (Most of the CPU time is spent in compression which gets thrown away if the content turns out to be already stored). A more advanced approach is to store components in OSTree itself, then union them, and recommit them. At this point, we recommend taking a look at the OSTree API, and choose a programming language supported by GObject Introspection to write your buildsystem scripts. Python may be a good choice, or you could choose custom C code, etc. For the purposes of this tutorial we will use shell script, but it’s strongly recommended to choose a real programming language for your build system. Let’s say that your build system produces separate artifacts (whether those are RPMs, zip files, or whatever). These artifacts should be the result of make install DESTDIR= or similar. Basically equivalent to RPMs/debs. Further, in order to make things fast, we will need a separate bare-user repository in order to perform checkouts quickly via hardlinks. We’ll then export content into the archive repository for use by client systems. mkdir build-repo ostree --repo=build-repo init --mode=bare-user . You can begin committing those as individual branches: . ostree --repo=build-repo commit -b exampleos/x86_64/bash --tree=tar=bash-4.2-bin.tar.gz ostree --repo=build-repo commit -b exampleos/x86_64/systemd --tree=tar=systemd-224-bin.tar.gz . Set things up so that whenever a package changes, you redo the commit with the new package version - conceptually, the branch tracks the individual package versions over time, and defaults to “latest”. This isn’t required - one could also include the version in the branch name, and have metadata outside to determine “latest” (or the desired version). Now, to construct our final tree: . rm -rf exampleos-build for package in bash systemd; do ostree --repo=build-repo checkout -U --union exampleos/x86_64/${package} exampleos-build done # Set up a \"rofiles-fuse\" mount point; this ensures that any processes # we run for post-processing of the tree don't corrupt the hardlinks. mkdir -p mnt rofiles-fuse exampleos-build mnt # Now run global \"triggers\", generate cache files: ldconfig -r mnt (Insert other programs here) fusermount -u mnt ostree --repo=build-repo commit -b exampleos/x86_64/standard --link-checkout-speedup exampleos-build . There are a number of interesting things going on here. The major architectural change is that we’re using --link-checkout-speedup. This is a way to tell OSTree that our checkout is made via hardlinks, and to scan the repository in order to build up a reverse (device, inode) -> checksum mapping. In order for this mapping to be accurate, we needed the rofiles-fuse to ensure that any changed files had new inodes (and hence a new checksum). ", + "url": "/ostree/buildsystem-and-repos/#constructing-trees-from-unions", + + "relUrl": "/buildsystem-and-repos/#constructing-trees-from-unions" + },"55": { + "doc": "Writing a buildsystem and managing repositories", + "title": "Migrating content between repositories", + "content": "Now that we have content in our build-repo repository (in bare-user mode), we need to move the exampleos/x86_64/standard branch content into the repository just named repo (in archive mode) for export, which will involve zlib compression of new objects. We likely want to generate static deltas after that as well. Let’s copy the content: . ostree --repo=repo pull-local build-repo exampleos/x86_64/standard . Clients can now incrementally download new objects - however, this would also be a good time to generate a delta from the previous commit. ostree --repo=repo static-delta generate exampleos/x86_64/standard . ", + "url": "/ostree/buildsystem-and-repos/#migrating-content-between-repositories", + + "relUrl": "/buildsystem-and-repos/#migrating-content-between-repositories" + },"56": { + "doc": "Writing a buildsystem and managing repositories", + "title": "More sophisticated repository management", + "content": "Next, see Repository Management for the next steps in managing content in OSTree repositories. ", + "url": "/ostree/buildsystem-and-repos/#more-sophisticated-repository-management", + + "relUrl": "/buildsystem-and-repos/#more-sophisticated-repository-management" + },"57": { + "doc": "Using composefs with OSTree", + "title": "Using composefs with OSTree", + "content": ". | composefs . | Enabling composefs (unsigned) | composefs configuration | Injecting composefs digests | Signatures | . | Requirements | Status | Compatiblity | Comparison with other approaches | Further references | . ", + "url": "/ostree/composefs/", + + "relUrl": "/composefs/" + },"58": { + "doc": "Using composefs with OSTree", + "title": "composefs", + "content": "The composefs project is a new hybrid Linux stacking filesystem that provides many benefits when used for bootable host systems, such as a strong story for integrity. At the current time, integration of composefs and ostree is experimental. This issue tracks the latest status. Enabling composefs (unsigned) . When building a disk image or to transition an existing system, run: . ostree config --repo=/ostree/repo set ex-integrity.composefs true . This will ensure that any future deployments (e.g. created by ostree admin upgrade) have a .ostree.cfs file in the deployment directory which is a mountable composefs metadata file, with a “backing store” directory that is shared with the current /ostree/repo/objects. composefs configuration . The ostree-prepare-root binary will look for ostree/prepare-root.conf in /etc and /usr/lib in the initramfs. Using that configuration file you can enable composefs, and specify an Ed25519 public key to validate the booted commit. See the manpage for ostree-prepare-root for details of how to configure it. Injecting composefs digests . When generating an OSTree commit, there is a CLI switch --generate-composefs-metadata and a corresponding C API ostree_repo_commit_add_composefs_metadata. This will inject the composefs digest as metadata into the ostree commit under a metadata key ostree.composefs.v0. Because an OSTree commit can be signed, this allows covering the composefs fsverity digest with a signature. Signatures . If a commit is signed with an Ed25519 private key (see ostree --sign), and composefs.keyfile is specified in prepare-root.conf, then the initrd will find the commit being booted in the system repo and validate its signature against the public key. It will then ensure that the composefs digest being booted has an fs-verity digest matching the one in the commit. This allows a fully trusted read-only /usr. The exact usage of the signature is up to the user, but a common way to use it with transient keys. This is done like this: . | Generate a new keypair before each build | Embed the public key in the initrd that is part of the commit. | Ensure the initrd has a prepare-root.conf with [composefs] enabled=signed, and either use keypath or inject /etc/ostree/initramfs-root-binding.key; for more see man ostree-prepare-root | After committing, run ostree --sign with the private key. | Throw away the private key. | . When a transient key is used this way, that ties the initrd with the userspace part from the commit. This means each initrd can only boot the very same userspace it was made for. For example, if an older version of the OS has a security flaw, you can’t boot a new fixed (signed) initrd and have it boot the older userspace with the flaw. ", + "url": "/ostree/composefs/#composefs", + + "relUrl": "/composefs/#composefs" + },"59": { + "doc": "Using composefs with OSTree", + "title": "Requirements", + "content": "The current default composefs integration in ostree does not have any requirements from the underlying kernel and filesystem other than having the following kernel options set: . | CONFIG_OVERLAY_FS | CONFIG_BLK_DEV_LOOP | CONFIG_EROFS_FS | . At the current time, there are no additional userspace runtime requirements. ", + "url": "/ostree/composefs/#requirements", + + "relUrl": "/composefs/#requirements" + },"60": { + "doc": "Using composefs with OSTree", + "title": "Status", + "content": "IMPORTANT The integration with composefs is experimental and subject to change. Please try it and report issues but do not deploy to production systems yet. ", + "url": "/ostree/composefs/#status", + + "relUrl": "/composefs/#status" + },"61": { + "doc": "Using composefs with OSTree", + "title": "Compatiblity", + "content": "One issue that ostree users transitioning to composefs may hit is that it is no longer possible to add new toplevel directories via the chattr -i / && mkdir /somedir && chattr -i trick. A bit more on this in the following issues: . | https://github.com/coreos/rpm-ostree/issues/337 | https://github.com/ostreedev/ostree/pull/2681 | . However, users who were doing things like this probably want to enable the root.transient option; see man ostree-prepare-root which will allow this (but also change other behaviors too). ", + "url": "/ostree/composefs/#compatiblity", + + "relUrl": "/composefs/#compatiblity" + },"62": { + "doc": "Using composefs with OSTree", + "title": "Comparison with other approaches", + "content": "There is also support for using IMA with ostree. In short, composefs provides much stronger and more efficient integrity: . | composefs validates an entire filesystem tree, not just individual files | composefs makes files actually read-only, whereas IMA does not by default | composefs uses fs-verity which does on-demand verification (IMA by default does a full readahead of every file accessed, though IMA can also use fs-verity as a backend) | . ", + "url": "/ostree/composefs/#comparison-with-other-approaches", + + "relUrl": "/composefs/#comparison-with-other-approaches" + },"63": { + "doc": "Using composefs with OSTree", + "title": "Further references", + "content": ". | https://github.com/containers/composefs | https://www.kernel.org/doc/html/next/filesystems/fsverity.html | . ", + "url": "/ostree/composefs/#further-references", + + "relUrl": "/composefs/#further-references" + },"64": { + "doc": "OSTree Contributing Tutorial", + "title": "OSTree Contributing Tutorial", + "content": "The following guide is about OSTree forking, building, adding a command, testing the command, and submitting the change. | Getting Started | Building OSTree . | Install Build Dependencies | OSTree Build Commands . | Notes | Tip | . | . | Testing a Build . | Testing in a Container | Testing in a Virtual Machine | . | Tutorial: Adding a basic builtin command to ostree . | Modifying OSTree | Adding a new API function to libostree | OSTree Tests | Submitting a Patch | Returning Workflow | . | . ", + "url": "/ostree/contributing-tutorial/", + + "relUrl": "/contributing-tutorial/" + },"65": { + "doc": "OSTree Contributing Tutorial", + "title": "Getting Started", + "content": "Fork https://github.com/ostreedev/ostree, then run the following commands. $ git clone https://github.com/<username>/ostree && cd ostree $ git remote add upstream https://github.com/ostreedev/ostree $ git checkout main $ git fetch upstream && git branch --set-upstream-to=upstream/main main . Make a branch from main for your patch. $ git checkout -b <name-of-branch> $ git branch --set-upstream-to=upstream/main <name-of-branch> . ", + "url": "/ostree/contributing-tutorial/#getting-started", + + "relUrl": "/contributing-tutorial/#getting-started" + },"66": { + "doc": "OSTree Contributing Tutorial", + "title": "Building OSTree", + "content": "Install Build Dependencies . Execute one of the following group commands as superuser depending on your machine’s package manager. For Fedora: . $ dnf install @buildsys-build dnf-plugins-core && \\ dnf builddep ostree . For CentOS: . $ yum install yum-utils dnf-plugins-core && \\ yum-builddep ostree . For Debian based distros: . $ apt-get update && \\ apt-get install build-essential && \\ apt-get build-dep ostree . build.sh will have a list of packages needed to build ostree. OSTree Build Commands . These are the basic commands to build OSTree. Depending on the OS that OSTree will be built for, the flags or options for ./autogen.sh and ./configure will vary. See ostree-build.sh in this tutorial below for specific commands to building OSTree for Fedora 28 and Fedora 28 Atomic Host. # optional: autogen.sh will run this if necessary git submodule update --init env NOCONFIGURE=1 ./autogen.sh # run ./configure if makefile does not exist ./configure make make install DESTDIR=/path/to/install/binary . Notes . Running git submodule update --init is optional since autogen.sh will check to see if one of the submodule files for example from libglnx/ or from bsdiff/ exists. Additionally, autogen.sh will check to see if the environment variable NOCONFIGURE is set. To run ./configure manually, run autogen in a modified environment as such, env NOCONFIGURE=1 ./autogen.sh. Otherwise, leave NOCONFIGURE empty and autogen.sh will run ./configure as part of the autogen.sh command when it executes. For more information on --prefix see Variables for Installation Directories. make install will generate files for /bin and /lib. If DESTDIR is unspecified then OSTree will be installed in the default directory i.e. /usr/local/bin and its static libraries in /usr/local/lib. Note that the /usr/local portion of the path can be changed using the --prefix option for ./configure. See this GNU guide on DESTDIR Staged Installs for more information. Tip . Make allows parallel execution of recipes. Use make -j<N> to speed up the build. <N> is typically $((2 * $(nproc))) for optimal performance, where nproc is the number of processing units (CPU cores) available. See page 106 of the GNU Make Manual for more information about the --jobs or -j option. ", + "url": "/ostree/contributing-tutorial/#building-ostree", + + "relUrl": "/contributing-tutorial/#building-ostree" + },"67": { + "doc": "OSTree Contributing Tutorial", + "title": "Testing a Build", + "content": "It is best practice to build software (definitely including ostree) in a container or virtual machine first. Testing in a Container . There are a variety of container engines available and many distributions have pre-packaged versions of e.g. Podman and Docker. If you choose to use Docker upstream, you may want to follow this post-installation guide for Docker. This will allow you to run Docker as a non-root user on a Linux based host machine. You will need to have pushed a remote git branch $REMOTE_BRANCH (see ostree-git.sh below) in order to pull your changes into a container. The example below uses Docker to manage containers. Save the contents of this Dockerfile somewhere on your machine: . # this pulls the fedora 28 image FROM registry.fedoraproject.org/fedora:28 # install ostree dependencies RUN dnf update -y && \\ dnf -y install @buildsys-build dnf-plugins-core && \\ dnf -y builddep ostree && \\ dnf clean all # clone ostree and update main branch COPY ostree-git.sh / RUN ../ostree-git.sh # builds ostree + any additional commands COPY ostree-build.sh / # entry into the container will start at this directory WORKDIR /ostree # run the following as `/bin/sh -c` # or enter the container to execute ./ostree-build.sh RUN ../ostree-build.sh . Save the following bash scripts in the same directory as the Dockerfile. Then change the mode bit of these files so that they are executable, by running chmod +x ostree-git.sh ostree-build.sh . #!/bin/bash # ostree-git.sh # Clone ostree and update main branch set -euo pipefail # Set $USERNAME to your GitHub username here. USERNAME=\"\" # clone your fork of the OSTree repo, this will be in the \"/\" directory git clone https://github.com/$USERNAME/ostree.git cd ostree # Add upstream as remote and update main branch git checkout main git remote add upstream https://github.com/ostreedev/ostree.git git pull --rebase upstream main . #!/bin/bash # ostree-build.sh # Build and test OSTree set -euo pipefail # $REMOTE_BRANCH is the name of the remote branch in your # repository that contains changes (e.g. my-patch). REMOTE_BRANCH=\"\" # fetch updates from origin # origin url should be your forked ostree repository git fetch origin # go to branch with changes # if this branch already exists then checkout that branch exit_code=\"$(git checkout --track origin/$REMOTE_BRANCH; echo $?)\" if [[ \"$exit_code\" == 1 ]] then echo \"This branch:\" $REMOTE_BRANCH \"is not a remote branch.\" exit fi # make sure branch with changes is up-to-date git pull origin $REMOTE_BRANCH # build OSTree commands for Fedora 28 and Fedora 28 Atomic Host ./autogen.sh --prefix=/usr --libdir=/usr/lib64 --sysconfdir=/etc ./configure --prefix=/usr make -j$((2 * $(nproc))) make install # any additional commands go here . Build the container . Run docker build in the same directory of the Dockerfile like so: . $ docker build -t ostree-fedora-test . When this build is done, the -t option tags the image as ostree-fedora-test. Note: Do not forget the dot . at the end of the above command which specifies the location of the Dockerfile. You will see ostree-fedora-test listed when running docker images: . REPOSITORY TAG IMAGE ID CREATED SIZE ostree-fedora-test latest 817c04cc3656 1 day ago 978MB . Entering the Container . To start the ostree-fedora-test container, run: . $ docker run -it --rm --entrypoint /bin/sh --name ostree-testing ostree-fedora-test . Note: . --rm option tells Docker to automatically clean up the container and remove the file system when the container exits. Otherwise remove it manually by running docker rm <container name>. The state of the container will not be saved when the shell prompt exits. Best practice is modify the Dockerfile to modify the image. Testing in a Container Workflow . | Edit the changes to OSTree on your local machine. | git add to stage the changed files, git commit and then git push origin <local-branch>:<remote-branch>. | Testing on a new container vs. Testing on an existing container: . If the ostree-testing container was newly built right after your changes have been committed, then the container’s build of ostree should contain your changes. Else: Within the ostree-testing container, run ../ostree-build.sh in the ostree directory. This will pull in changes from your branch and create a new ostree build. | make install will install OSTree in the default location i.e. /usr/..in a Fedora 28 container. | Test ostree. | . Testing in a Virtual Machine . To create a Fedora 28 Atomic Host Vagrant VM, run the following commands: . $ mkdir atomic && cd atomic $ vagrant init fedora/28-atomic-host && vagrant up . An option is to use rsync to transfer ostree files to a Vagrant VM. To find the IP address of a Vagrant VM, run vagrant ssh-config in the same directory as the Vagrantfile. Steps to rsync files to test an ostree build: . | Copy the contents of your public ssh key on your host machine e.g. id_rsa.pub to /home/vagrant/.ssh/authorized_keys on the VM. | Run sudo su, followed by ssh localhost then press Ctrl+c to exit from the decision prompt. This will create the .ssh directory with the right permissions. | Using Vagrant as the user, run sudo cp ~/.ssh/authorized_keys /root/.ssh/. So that user root has the the same login credentials. | To override the Read-only file system warning, run sudo ostree admin unlock. | <ostree-install-dir> will serve as the local install location for ostree and the path to this directory should be absolute when specified in DESTDIR. | Set rsync to sync changes in /etc and /usr from <ostree-install-dir>/ on the host to the VM: . $ rsync -av <ostree-install-dir>/etc/ root@<ip-address>:/etc $ rsync -av <ostree-install-dir>/usr/ root@<ip-address>:/usr . Using option -n will execute the commands as a trial, which is helpful to list the files that will be synced. | Run the commands in step 6 each time a new ostree build is executed to update the change. Running ls -lt in the directory where the changed file is expected, is a simple way to check when a particular file was last modified. Proceed to the test changes ostree with the most recent changes. | . ", + "url": "/ostree/contributing-tutorial/#testing-a-build", + + "relUrl": "/contributing-tutorial/#testing-a-build" + },"68": { + "doc": "OSTree Contributing Tutorial", + "title": "Tutorial: Adding a basic builtin command to ostree", + "content": "Modifying OSTree . This will add a command which prints Hello OSTree! when ostree hello-ostree is entered. | Create a file in src/ostree named ot-builtin-hello-ostree.c. Code that lives in here belongs to OSTree, and uses functionality from libostree. | Add the following to ot-builtin-hello-ostree.c: . #include \"config.h\" #include \"ot-main.h\" #include \"ot-builtins.h\" #include \"ostree.h\" #include \"otutil.h\" // Structure for options such as ostree hello-ostree --option. static GOptionEntry options[] = { { NULL }, }; gboolean ostree_builtin_hello_ostree (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error) { g_autoptr(OstreeRepo) repo = NULL; // Creates new command context, ready to be parsed. // Input to g_option_context_new shows when running ostree <command> --help g_autoptr(GOptionContext) context = g_option_context_new (\"\"); // Parses the command context according to the ostree CLI. if (!ostree_option_context_parse (context, options, &argc, &argv, invocation, &repo, cancellable, error)) return FALSE; g_print(\"Hello OSTree!\\n\"); return TRUE; } . This defines the functionality for hello-ostree. Now we have to make sure the CLI can refer to the execution function, and that autotools knows to build this file. Note: libostree codebase supports C99 features. | Add the following in src/ostree/main.c: . { \"hello-ostree\", // The name of the command OSTREE_BUILTIN_FLAG_NO_REPO, // Flag not to require the `--repo` argument, see \"ot-main.h\" ostree_builtin_hello_ostree, // Execution function for the command \"Print hello message\" }, // Short description to appear when `ostree hello-ostree --help` is entered . | Add a macro for the function declaration of ostree_builtin_hello_ostree, in ot-builtins.h: . BUILTINPROTO(hello_ostree); . This makes the function definition visible to the CLI. | Configure automake to include ot-builtin-hello-ostree.c in the build, by adding an entry in Makefile-ostree.am under ostree_SOURCES: . src/ostree/ot-builtin-hello-ostree.c \\ . | Rebuild ostree: . $ make && make install DESTDIR=/path/to/install/the/content . | Execute the new ostree binary, from where you installed it: . $ ostree hello-ostree Hello OSTree! . | . Adding a new API function to libostree . This will add a new API function ostree_kernel_args_foo() in src/libostree/ostree-kernel-args.c. | Add the following to src/libostree/ostree-kernel-args.h: _OSTREE_PUBLIC gboolean ostree_kernel_args_foo (const char *arg, GCancellable *cancellable, GError **error); . | Add the following to ostree-kernel-args.c: /** * ostree_kernel_args_foo: * @arg: Description of the arg * * Description of the function * * Since: $NEWVERSION //The new libostree version, for example 2022.5 **/ gboolean ostree_kernel_args_foo (const char *arg, GCancellable *cancellable, GError **error) { //Add code here } . | Add the following to src/libostree/libostree-devel.sym: LIBOSTREE_$NEWVERSION { // The new libostree version global: ostree_kernel_args_foo; // Function name } LIBOSTREE_$LASTSTABLE; // The last stable libostree version . | Add the following to Makefile-libostree.am: if BUILDOPT_IS_DEVEL_BUILD symbol_files += $(top_srcdir)/src/libostree/libostree-devel.sym endif . | Add function name ostree_kernel_args_foo to apidoc/ostree-sections.txt under <FILE>ostree-kernel-args</FILE>. | Call function ostree_kernel_args_foo() in your code. | . OSTree Tests . Tests for OSTree are done by shell scripting, by running OSTree commands and examining output. These steps will go through adding a test for hello-ostree. | Create a file in tests called test-hello-ostree.sh. | Add the following to test-hello-ostree.sh: . set -euo pipefail # Ensure the test will not silently fail . $(dirname $0)/libtest.sh # Make libtest.sh functions available echo \"1..1\" # Declare which test is being run out of how many pushd ${test_tmpdir} ${CMD_PREFIX} ostree hello-ostree > hello-output.txt assert_file_has_content hello-output.txt \"Hello OSTree!\" popd echo \"ok hello ostree\" # Indicate test success . Many tests require a fake repository setting up (as most OSTree commands require --repo to be specified). See test-pull-depth.sh for an example of this setup. | Configure automake to include test-hello-ostree.sh in the build, by adding an entry in Makefile-tests.am under _installed_or_uninstalled_test_scripts: . tests/test-hello-ostree.sh \\ . | Make sure test-hello-ostree.sh has executable permissions! . $ chmod +x tests/test-hello-ostree.sh . | Run the test: . $ make check TESTS=\"tests/test-hello-ostree.sh\" . Multiple tests can be specified: make check TESTS=\"test1 test2 ...\". To run all tests, use make check. Hopefully, the test passes! The following will be printed: . PASS: tests/test-hello-ostree.sh 1 hello ostree ============================================================================ Testsuite summary for libostree 2018.8 ============================================================================ # TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ============================================================================ . | . Submitting a Patch . After you have committed your changes and tested, you are ready to submit your patch! . You should make sure your commits are placed on top of the latest changes from upstream/main: . $ git pull --rebase upstream main . To submit your patch, open a pull request from your forked repository. Most often, you’ll be merging into ostree:main from <username>:<branch name>. If some of your changes are complete and you would like feedback, you may also open a pull request that has WIP (Work In Progress) in the title. Before a pull request is considered merge ready, your commit messages should fall within the specified guideline. See Commit message style. See CONTRIBUTING.md for information on squashing commits, and alternative options to submit patches. Returning Workflow . When returning to work on a patch, it is recommended to update your fork with the latest changes in the upstream main branch. If creating a new branch: . $ git checkout main $ git pull upstream main $ git checkout -b <name-of-patch> . If continuing on a branch already created: . $ git checkout <name-of-patch> $ git pull --rebase upstream main . ", + "url": "/ostree/contributing-tutorial/#tutorial-adding-a-basic-builtin-command-to-ostree", + + "relUrl": "/contributing-tutorial/#tutorial-adding-a-basic-builtin-command-to-ostree" + },"69": { + "doc": "Deployments", + "title": "Deployments", + "content": ". | Overview . | “stateroot” (AKA “osname”): Group of deployments that share /var | Contents of a deployment | Staged deployments | The system /boot | . | . ", + "url": "/ostree/deployment/", + + "relUrl": "/deployment/" + },"70": { + "doc": "Deployments", + "title": "Overview", + "content": "Built on top of the OSTree versioning filesystem core is a layer that knows how to deploy, parallel install, and manage Unix-like operating systems (accessible via ostree admin). The core content of these operating systems are treated as read-only, but they transparently share storage. A deployment is physically located at a path of the form /ostree/deploy/$stateroot/deploy/$checksum. OSTree is designed to boot directly into exactly one deployment at a time; each deployment is intended to be a target for chroot() or equivalent. “stateroot” (AKA “osname”): Group of deployments that share /var . Each deployment is grouped in exactly one “stateroot” (also known as an “osname”); the former term is preferred. From above, you can see that a stateroot is physically represented in the /ostree/deploy/$stateroot directory. For example, OSTree can allow parallel installing Debian in /ostree/deploy/debian and Red Hat Enterprise Linux in /ostree/deploy/rhel (subject to operating system support, present released versions of these operating systems may not support this). Each stateroot has exactly one copy of the traditional Unix /var, stored physically in /ostree/deploy/$stateroot/var. OSTree provides support tools for systemd to create a Linux bind mount that ensures the booted deployment sees the shared copy of /var. OSTree does not touch the contents of /var. Operating system components such as daemon services are required to create any directories they require there at runtime (e.g. /var/cache/$daemonname), and to manage upgrading data formats inside those directories. Contents of a deployment . A deployment begins with a specific commit (represented as a SHA256 hash) in the OSTree repository in /ostree/repo. This commit refers to a filesystem tree that represents the underlying basis of a deployment. For short, we will call this the “tree”, to distinguish it from the concept of a deployment. First, the tree must include a kernel (and optionally an initramfs). The current standard locations for these are /usr/lib/modules/$kver/vmlinuz and /usr/lib/modules/$kver/initramfs.img. The “boot checksum” will be computed automatically. This follows the current Fedora kernel layout, and is the current recommended path. However, older versions of libostree don’t support this; you may need to also put kernels in the previous (legacy) paths, which are vmlinuz(-.*)?-$checksum in either /boot or /usr/lib/ostree-boot. The checksum should be a SHA256 hash of the kernel contents; it must be pre-computed before storing the kernel in the repository. Optionally, the directory can also contain an initramfs, stored as initramfs(-.*)?-$checksum and/or a device tree, stored as devicetree(-.*)?-$checksum. If an initramfs or devicetree exist, the checksum must include all of the kernel, initramfs and devicetree contents. OSTree will use this to determine which kernels are shared. The rationale for this is to avoid computing checksums on the client by default. The deployment should not have a traditional UNIX /etc; instead, it should include /usr/etc. This is the “default configuration”. When OSTree creates a deployment, it performs a 3-way merge using the old default configuration, the active system’s /etc, and the new default configuration. In the final filesystem tree for a deployment then, /etc is a regular writable directory. Besides the exceptions of /var and /etc then, the rest of the contents of the tree are checked out as hard links into the repository. It’s strongly recommended that operating systems ship all of their content in /usr, but this is not a hard requirement. Finally, a deployment may have a .origin file, stored next to its directory. This file tells ostree admin upgrade how to upgrade it. At the moment, OSTree only supports upgrading a single refspec. However, in the future OSTree may support a syntax for composing layers of trees, for example. Staged deployments . As mentioned above, when OSTree creates a new deployment, a 3-way merge is done to update its /etc. Depending on the nature of the system, this can cause an issue: if a user or program modifies the booted /etc after the pending deployment is created but before rebooting, those modifications will be lost. OSTree does not do a second /etc merge on reboot. To counter this, OSTree supports staged deployments. In this flow, deployments are created using e.g. ostree admin upgrade --stage on the CLI. The new deployment is still created when the command is invoked, but the 3-way /etc merge is delayed until the system is rebooted or shut down. Additionally, updating the bootloader is also delayed. This is done by the ostree-finalize-staged.service systemd unit. The main disadvantage of this approach is that rebooting can take longer and the failure mode can be confusing (the machine will reboot into the same deployment). In systems where the workload is well-understood and not subject to the /etc issue above, it may be better to not stage deployments. The system /boot . While OSTree parallel installs deployments cleanly inside the /ostree directory, ultimately it has to control the system’s /boot directory. The way this works is via the Boot Loader Specification, which is a standard for bootloader-independent drop-in configuration files. When a tree is deployed, it will have a configuration file generated of the form /boot/loader/entries/ostree-$stateroot-$checksum.$serial.conf. This configuration file will include a special ostree= kernel argument that allows the initramfs to find (and chroot() into) the specified deployment. At present, not all bootloaders implement the BootLoaderSpec, so OSTree contains code for some of these to regenerate native config files (such as /boot/syslinux/syslinux.conf) based on the entries. ", + "url": "/ostree/deployment/#overview", + + "relUrl": "/deployment/#overview" + },"71": { + "doc": "OSTree data formats", + "title": "OSTree data formats", + "content": ". | On the topic of “smart servers” | The archive format | archive efficiency | Aside: bare formats | Static deltas | Static delta repository layout | Static delta internal structure . | The delta superblock | . | A delta part | Fallback objects | . ", + "url": "/ostree/formats/", + + "relUrl": "/formats/" + },"72": { + "doc": "OSTree data formats", + "title": "On the topic of “smart servers”", + "content": "One really crucial difference between OSTree and git is that git has a “smart server”. Even when fetching over https://, it isn’t just a static webserver, but one that e.g. dynamically computes and compresses pack files for each client. In contrast, the author of OSTree feels that for operating system updates, many deployments will want to use simple static webservers, the same target most package systems were designed to use. The primary advantages are security and compute efficiency. Services like Amazon S3 and CDNs are a canonical target, as well as a stock static nginx server. ", + "url": "/ostree/formats/#on-the-topic-of-smart-servers", + + "relUrl": "/formats/#on-the-topic-of-smart-servers" + },"73": { + "doc": "OSTree data formats", + "title": "The archive format", + "content": "In the repo section, the concept of objects was introduced, where file/content objects are checksummed and managed individually. (Unlike a package system, which operates on compressed aggregates). The archive format simply gzip-compresses each content object. Metadata objects are stored uncompressed. This means that it’s easy to serve via static HTTP. Note: the repo config file still uses the historical term archive-z2 as mode. But this essentially indicates the modern archive format. When you commit new content, you will see new .filez files appearing in objects/. ", + "url": "/ostree/formats/#the-archive-format", + + "relUrl": "/formats/#the-archive-format" + },"74": { + "doc": "OSTree data formats", + "title": "archive efficiency", + "content": "The advantages of archive: . | It’s easy to understand and implement | Can be served directly over plain HTTP by a static webserver | Clients can download/unpack updates incrementally | Space efficient on the server | . The biggest disadvantage of this format is that for a client to perform an update, one HTTP request per changed file is required. In some scenarios, this actually isn’t bad at all, particularly with techniques to reduce HTTP overhead, such as HTTP/2. In order to make this format work well, you should design your content such that large data that changes infrequently (e.g. graphic images) are stored separately from small frequently changing data (application code). Other disadvantages of archive: . | It’s quite bad when clients are performing an initial pull (without HTTP/2), | One doesn’t know the total size (compressed or uncompressed) of content before downloading everything | . ", + "url": "/ostree/formats/#archive-efficiency", + + "relUrl": "/formats/#archive-efficiency" + },"75": { + "doc": "OSTree data formats", + "title": "Aside: bare formats", + "content": "The most common operation is to pull from a remote archive repository into a local one. This latter is not compressed on disk. In other words, pulling to a local repository is similar to unpacking (but not installing) the content of an RPM/deb package. The bare repository format is the simplest one. In this mode regular files are directly stored to disk, and all metadata (e.g. uid/gid and xattrs) is reflected to the filesystem. It allows further direct access to content and metadata, but it may require elevated privileges when writing objects to the repository. The bare-user format is a bit special in that the uid/gid and xattrs from the content are ignored. This is primarily useful if you want to have the same OSTree-managed content that can be run on a host system or an unprivileged container. Similarly, the bare-split-xattrs format is a special mode where xattrs are stored as separate repository objects, and not directly reflected to the filesystem. This is primarily useful when transporting xattrs through lossy environments (e.g. tar streams and containerized environments). It also allows carrying security-sensitive xattrs (e.g. SELinux labels) out-of-band without involving OS filesystem logic. ", + "url": "/ostree/formats/#aside-bare-formats", + + "relUrl": "/formats/#aside-bare-formats" + },"76": { + "doc": "OSTree data formats", + "title": "Static deltas", + "content": "OSTree itself was originally focused on a continuous delivery model, where client systems are expected to update regularly. However, many OS vendors would like to supply content that’s updated e.g. once a month or less often. For this model, we can do a lot better to support batched updates than a basic archive repo. However, we still want to preserve the model of “static webserver only”. Given this, OSTree has gained the concept of a “static delta”. These deltas are targeted to be a delta between two specific commit objects, including “bsdiff” and “rsync-style” deltas within a content object. Static deltas also support from NULL, where the client can more efficiently download a commit object from scratch - this is mostly useful when using OSTree for containers, rather than OS images. For OS images, one tends to download an installer ISO or qcow2 image which is a single file that contains the tree data already. Effectively, we’re spending server-side storage (and one-time compute cost), and gaining efficiency in client network bandwidth. ", + "url": "/ostree/formats/#static-deltas", + + "relUrl": "/formats/#static-deltas" + },"77": { + "doc": "OSTree data formats", + "title": "Static delta repository layout", + "content": "Since static deltas may not exist, the client first needs to attempt to locate one. Suppose a client wants to retrieve commit ${new} while currently running ${current}. In order to save space, these two commits are “modified base64” - the / character is replaced with _. Like the commit objects, a “prefix directory” is used to make management easier for filesystem tools. A delta is named $(mbase64 $from)-$(mbase64 $to), for example GpTyZaVut2jXFPWnO4LJiKEdRTvOw_mFUCtIKW1NIX0-L8f+VVDkEBKNc1Ncd+mDUrSVR4EyybQGCkuKtkDnTwk, which in SHA256 format is 1a94f265a56eb768d714f5a73b82c988a11d453bcec3f985502b48296d4d217d-2fc7fe5550e410128d73535c77e98352b495478132c9b4060a4b8ab640e74f09. Finally, the actual content can be found in deltas/$fromprefix/$fromsuffix-$to. ", + "url": "/ostree/formats/#static-delta-repository-layout", + + "relUrl": "/formats/#static-delta-repository-layout" + },"78": { + "doc": "OSTree data formats", + "title": "Static delta internal structure", + "content": "A delta is itself a directory. Inside, there is a file called superblock which contains metadata. The rest of the files will be integers bearing packs of content. The file format of static deltas should be currently considered an OSTree implementation detail. Obviously, nothing stops one from writing code which is compatible with OSTree today. However, we would like the flexibility to expand and change things, and having multiple codebases makes that more problematic. Please contact the authors with any requests. That said, one critical thing to understand about the design is that delta payloads are a bit more like “restricted programs” than they are raw data. There’s a “compilation” phase which generates output that the client executes. This “updates as code” model allows for multiple content generation strategies. The design of this was inspired by that of Chromium: ChromiumOS Autoupdate. The delta superblock . The superblock contains: . | arbitrary metadata | delta generation timestamp | the new commit object | An array of recursive deltas to apply | An array of per-part metadata, including total object sizes (compressed and uncompressed), | An array of fallback objects | . Let’s define a delta part, then return to discuss details: . ", + "url": "/ostree/formats/#static-delta-internal-structure", + + "relUrl": "/formats/#static-delta-internal-structure" + },"79": { + "doc": "OSTree data formats", + "title": "A delta part", + "content": "A delta part is a combination of a raw blob of data, plus a very restricted bytecode that operates on it. Say for example two files happen to share a common section. It’s possible for the delta compilation to include that section once in the delta data blob, then generate instructions to write out that blob twice when generating both objects. Realistically though, it’s very common for most of a delta to just be “stream of new objects” - if one considers it, it doesn’t make sense to have too much duplication inside operating system content at this level. So then, what’s more interesting is that OSTree static deltas support a per-file delta algorithm called bsdiff that most notably works well on executable code. The current delta compiler scans for files with matching basenames in each commit that have a similar size, and attempts a bsdiff between them. (It would make sense later to have a build system provide a hint for this - for example, files within a same package). A generated bsdiff is included in the payload blob, and applying it is an instruction. ", + "url": "/ostree/formats/#a-delta-part", + + "relUrl": "/formats/#a-delta-part" + },"80": { + "doc": "OSTree data formats", + "title": "Fallback objects", + "content": "It’s possible for there to be large-ish files which might be resistant to bsdiff. A good example is that it’s common for operating systems to use an “initramfs”, which is itself a compressed filesystem. This “internal compression” defeats bsdiff analysis. For these types of objects, the delta superblock contains an array of “fallback objects”. These objects aren’t included in the delta parts - the client simply fetches them from the underlying .filez object. ", + "url": "/ostree/formats/#fallback-objects", + + "relUrl": "/formats/#fallback-objects" + },"81": { + "doc": "Using Linux IMA with OSTree", + "title": "Using Linux IMA with OSTree", + "content": ". | Linux IMA | IMA signatures and OSTree checksum | Signing . | Generating a key | Signing a commit | Applying a policy | Linux EVM | . | Further references | . ", + "url": "/ostree/ima/", + + "relUrl": "/ima/" + },"82": { + "doc": "Using Linux IMA with OSTree", + "title": "Linux IMA", + "content": "The Linux Integrity Measurement Architecture provides a mechanism to cryptographically sign the digest of a regular file, and policies can be applied to e.g. require that code executed by the root user have a valid signed digest. The alignment between Linux IMA and ostree is quite strong. OSTree provides a content-addressable object store, where files are intended to be immutable. This is implemented with a basic read-only bind mount. While IMA does not actually prevent mutating files, any changed (or unsigned) files would (depending on policy) not be readable or executable. ", + "url": "/ostree/ima/#linux-ima", + + "relUrl": "/ima/#linux-ima" + },"83": { + "doc": "Using Linux IMA with OSTree", + "title": "IMA signatures and OSTree checksum", + "content": "Mechanically, IMA signatures appear as a security.ima extended attribute on the file. This is a signed digest of just the file content (and not any metadata) . OSTree’s checksums in contrast include not just the file content, but also metadata such as uid, gid and mode and extended attributes; . Together, this means that adding an IMA signature to a file in the OSTree model appears as a new object (with a new digest). A nice property is that this enables the transactional addition (or removal) of IMA signatures. However, adding IMA signatures to files that were previously unsigned also today duplicates disk space. ", + "url": "/ostree/ima/#ima-signatures-and-ostree-checksum", + + "relUrl": "/ima/#ima-signatures-and-ostree-checksum" + },"84": { + "doc": "Using Linux IMA with OSTree", + "title": "Signing", + "content": "To apply IMA signatures to an OSTree commit, there is an ima-sign command implemented currently in the ostree-rs-ext project. Generating a key . There is documentation for this in man evmctl and the upstream IMA page; we will not replicate it here. Signing a commit . ima-sign requires 4 things: . | An OSTree repository (could be any mode; archive or e.g. bare-user) | A ref or commit digest (e.g. exampleos/x86_64/stable) | A digest algorithm (usually sha256, but you may use e.g. sha512 as well) | An RSA private key | . You can then add IMA signatures to all regular files in the commit: . $ ostree-ext-cli ima-sign --repo=repo exampleos/x86_64/stable sha256 /path/to/key.pem . Many different choices are possible for the signing model. For example, your build system could store individual components/packages in their own ostree refs, and sign them at build time. This would avoid re-signing all binaries when creating production builds. Although note you still likely want to sign generated artifacts from unioning individual components, such as a dpkg/rpm database or equivalent and cache files such as the ldconfig and GTK+ icon caches, etc. Applying a policy . Signing a commit by itself will have little to no effect. You will also need to include in your builds an IMA policy. Linux EVM . The EVM subsystem builds on IMA, and adds another signature which covers most file data, such as the uid, gid and mode and selected security-relevant extended attributes. This is quite close to the ostree native checksum - the ordering of the fields is different so the checksums are physically different, but logically they are very close. However, the focus of the EVM design seems to mostly be on machine-specific signatures with keys stored in a TPM. Note that doing this on a per-machine basis would add a new security.evm extended attribute, and crucially that changes the ostree digest - so from ostree’s perspective, these objects will appear corrupt. In the future, ostree may learn to ignore the presence of security.evm extended attributes. There is also some support for “portable” EVM signatures - by default, EVM signatures also include the inode number and generation which are inherently machine-specific. A future ostree enhancement may instead also focus on supporting signing commits with these “portable” EVM signatures in addition to IMA. ", + "url": "/ostree/ima/#signing", + + "relUrl": "/ima/#signing" + },"85": { + "doc": "Using Linux IMA with OSTree", + "title": "Further references", + "content": ". | https://sourceforge.net/p/linux-ima/wiki/Home/ | https://en.opensuse.org/SDB:Ima_evm | https://wiki.gentoo.org/wiki/Integrity_Measurement_Architecture | https://fedoraproject.org/wiki/Changes/Signed_RPM_Contents | https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/managing_monitoring_and_updating_the_kernel/enhancing-security-with-the-kernel-integrity-subsystem_managing-monitoring-and-updating-the-kernel | . ", + "url": "/ostree/ima/#further-references", + + "relUrl": "/ima/#further-references" + },"86": { + "doc": "libostree", + "title": "libostree", + "content": ". | Operating systems and distributions using OSTree | Distribution build tools | Projects linking to libostree | Language bindings | Building | API Reference | Manual Pages | Contact and discussion forums | Contributing | Licensing | . This project is now known as “libostree”, though it is still appropriate to use the previous name: “OSTree” (or “ostree”). The focus is on projects which use libostree’s shared library, rather than users directly invoking the command line tools (except for build systems). However, in most of the rest of the documentation, we will use the term “OSTree”, since it’s slightly shorter, and changing all documentation at once is impractical. We expect to transition to the new name over time. As implied above, libostree is both a shared library and suite of command line tools that combines a “git-like” model for committing and downloading bootable filesystem trees, along with a layer for deploying them and managing the bootloader configuration. The core OSTree model is like git in that it checksums individual files and has a content-addressed-object store. It’s unlike git in that it “checks out” the files via hardlinks, and they thus need to be immutable to prevent corruption. Therefore, another way to think of OSTree is that it’s just a more polished version of Linux VServer hardlinks. Features: . | Transactional upgrades and rollback for the system | Replicating content incrementally over HTTP via GPG signatures and “pinned TLS” support | Support for parallel installing more than just 2 bootable roots | Binary history on the server side (and client) | Introspectable shared library API for build and deployment systems | Flexible support for multiple branches and repositories, supporting projects like Flatpak which use libostree for applications, rather than hosts. | . ", + "url": "/ostree/", + + "relUrl": "/" + },"87": { + "doc": "libostree", + "title": "Operating systems and distributions using OSTree", + "content": "Apertis uses libostree for their host system as well as Flatpak. See update documentation and apertis-update-manager . Endless OS uses libostree for their host system as well as Flatpak. See their eos-updater and deb-ostree-builder projects. For Debian/apt, see also https://github.com/stb-tester/apt2ostree and the LWN article Merkle trees and build systems. Fedora derivatives use rpm-ostree (noted below); there are 4 variants using OSTree: . | Fedora CoreOS | Fedora Silverblue | Fedora Kinoite | Fedora IoT | . Red Hat Enterprise Linux CoreOS is a derivative of Fedora CoreOS, used in OpenShift 4. The machine-config-operator manages upgrades. RHEL CoreOS is also the successor to RHEL Atomic Host, which uses rpm-ostree as well. Red Hat In-Vehicle Operating System (RHIVOS) is a derivative of CentOS Automotive Stream Distribution that uses OSTree, it’s closest Fedora derivative is Fedora IoT although it was created as it’s own distribution. GNOME Continuous is where OSTree was born - as a high performance continuous delivery/testing system for GNOME. GNOME OS is a testing OS that uses libostree for their host system as well as Flatpak. Liri OS has the option to install their distribution using ostree. Torizon OS is a Linux distribution for embedded systems that updates via OSTree images delivered via Uptane and aktualizr. ", + "url": "/ostree/#operating-systems-and-distributions-using-ostree", + + "relUrl": "/#operating-systems-and-distributions-using-ostree" + },"88": { + "doc": "libostree", + "title": "Distribution build tools", + "content": "meta-updater is a layer available for OpenEmbedded systems. QtOTA is Qt’s over-the-air update framework which uses libostree. The BuildStream build and integration tool supports importing and exporting from libostree repos. fedora-iot/otto is a tool that helps ship ostree commits inside Docker/OCI containers and run a webserver to serve the commits. Fedora coreos-assembler is the build tool used to generate Fedora CoreOS derivatives. debos is a tool-chain for simplifying the process of building a Debian-based OS image. gardenlinux/ostree-image-builder is a sample for building Debian-based OS images. It is not production ready but it might be useful to get started. ", + "url": "/ostree/#distribution-build-tools", + + "relUrl": "/#distribution-build-tools" + },"89": { + "doc": "libostree", + "title": "Projects linking to libostree", + "content": "rpm-ostree is used by the Fedora-derived operating systems listed above. It is a full hybrid image/package system. By default it uses libostree to atomically replicate a base OS (all dependency resolution is done on the server), but it supports “package layering”, where additional RPMs can be layered on top of the base. This brings a “best of both worlds”” model for image and package systems. eos-updater is a daemon that implements updates on EndlessOS. Flatpak uses libostree for desktop application containers. Unlike most of the other systems here, Flatpak does not use the “libostree host system” aspects (e.g. bootloader management), just the “git-like hardlink dedup”. For example, Flatpak supports a per-user OSTree repository. aktualizr is an Uptane-conformant software update client library intended for use in automotive and other security-sensitive embedded devices. It uses OSTree to manage the OS of the host device by default. ", + "url": "/ostree/#projects-linking-to-libostree", + + "relUrl": "/#projects-linking-to-libostree" + },"90": { + "doc": "libostree", + "title": "Language bindings", + "content": "libostree is accessible via GObject Introspection; any language which has implemented the GI binding model should work. For example, Both pygobject and gjs are known to work and further are actually used in libostree’s test suite today. Some bindings take the approach of using GI as a lower level and write higher level manual bindings on top; this is more common for statically compiled languages. Here’s a list of such bindings: . | ostree-go | ostree-rs | . ", + "url": "/ostree/#language-bindings", + + "relUrl": "/#language-bindings" + },"91": { + "doc": "libostree", + "title": "Building", + "content": "Releases are available as GPG signed git tags, and most recent versions support extended validation using git-evtag. However, in order to build from a git clone, you must update the submodules. If you’re packaging OSTree and want a tarball, I recommend using a “recursive git archive” script. There are several available online; this code in OSTree is an example. Once you have a git clone or recursive archive, building is the same as almost every autotools project: . git submodule update --init env NOCONFIGURE=1 ./autogen.sh ./configure --prefix=... make make install DESTDIR=/path/to/dest . ", + "url": "/ostree/#building", + + "relUrl": "/#building" + },"92": { + "doc": "libostree", + "title": "API Reference", + "content": "The libostree API documentation is available in Reference. ", + "url": "/ostree/#api-reference", + + "relUrl": "/#api-reference" + },"93": { + "doc": "libostree", + "title": "Manual Pages", + "content": "The ostree manual pages are available in Manual. ", + "url": "/ostree/#manual-pages", + + "relUrl": "/#manual-pages" + },"94": { + "doc": "libostree", + "title": "Contact and discussion forums", + "content": "There is also an #ostree channel on Libera.Chat as well as enabled Github discussions. ", + "url": "/ostree/#contact-and-discussion-forums", + + "relUrl": "/#contact-and-discussion-forums" + },"95": { + "doc": "libostree", + "title": "Contributing", + "content": "See Contributing. ", + "url": "/ostree/#contributing", + + "relUrl": "/#contributing" + },"96": { + "doc": "libostree", + "title": "Licensing", + "content": "The licensing for the code of libostree can be canonically found in the individual files; and the overall status in the COPYING file in the source. Currently, that’s LGPLv2+. This also covers the man pages and API docs. The license for the manual documentation in the doc/ directory is: SPDX-License-Identifier: (CC-BY-SA-3.0 OR GFDL-1.3-or-later) This is intended to allow use by Wikipedia and other projects. In general, files should have a SPDX-License-Identifier and that is canonical. ", + "url": "/ostree/#licensing", + + "relUrl": "/#licensing" + },"97": { + "doc": "OSTree Overview", + "title": "OSTree Overview", + "content": ". | Introduction | Hello World example | Comparison with “package managers” | Comparison with block/image replication | Atomic transitions between parallel-installable read-only filesystem trees | . ", + "url": "/ostree/introduction/", + + "relUrl": "/introduction/" + },"98": { + "doc": "OSTree Overview", + "title": "Introduction", + "content": "OSTree is an upgrade system for Linux-based operating systems that performs atomic upgrades of complete filesystem trees. It is not a package system; rather, it is intended to complement them. A primary model is composing packages on a server, and then replicating them to clients. The underlying architecture might be summarized as “git for operating system binaries”. It operates in userspace, and will work on top of any Linux filesystem. At its core is a git-like content-addressed object store with branches (or “refs”) to track meaningful filesystem trees within the store. Similarly, one can check out or commit to these branches. Layered on top of that is bootloader configuration, management of /etc, and other functions to perform an upgrade beyond just replicating files. You can use OSTree standalone in the pure replication model, but another approach is to add a package manager on top, thus creating a hybrid tree/package system. ", + "url": "/ostree/introduction/#introduction", + + "relUrl": "/introduction/#introduction" + },"99": { + "doc": "OSTree Overview", + "title": "Hello World example", + "content": "OSTree is mostly used as a library, but a quick tour of using its CLI tools can give a general idea of how it works at its most basic level. You can create a new OSTree repository using init: . $ ostree --repo=repo init . This will create a new repo directory containing your repository. Feel free to inspect it. Now, let’s prepare some data to add to the repo: . $ mkdir tree $ echo \"Hello world!\" > tree/hello.txt . We can now import our tree/ directory using the commit command: . $ ostree --repo=repo commit --branch=foo tree/ . This will create a new branch foo pointing to the full tree imported from tree/. In fact, we could now delete tree/ if we wanted to. To check that we indeed now have a foo branch, you can use the refs command: . $ ostree --repo=repo refs foo . We can also inspect the filesystem tree using the ls and cat commands: . $ ostree --repo=repo ls foo d00775 1000 1000 0 / -00664 1000 1000 13 /hello.txt $ ostree --repo=repo cat foo /hello.txt Hello world! . And finally, we can check out our tree from the repository: . $ ostree --repo=repo checkout foo tree-checkout/ $ cat tree-checkout/hello.txt Hello world! . ", + "url": "/ostree/introduction/#hello-world-example", + + "relUrl": "/introduction/#hello-world-example" + },"100": { + "doc": "OSTree Overview", + "title": "Comparison with “package managers”", + "content": "Because OSTree is designed for deploying core operating systems, a comparison with traditional “package managers” such as dpkg and rpm is illustrative. Packages are traditionally composed of partial filesystem trees with metadata and scripts attached, and these are dynamically assembled on the client machine, after a process of dependency resolution. In contrast, OSTree only supports recording and deploying complete (bootable) filesystem trees. It has no built-in knowledge of how a given filesystem tree was generated or the origin of individual files, or dependencies, descriptions of individual components. Put another way, OSTree only handles delivery and deployment; you will likely still want to include inside each tree metadata about the individual components that went into the tree. For example, a system administrator may want to know what version of OpenSSL was included in your tree, so you should support the equivalent of rpm -q or dpkg -L. The OSTree core emphasizes replicating read-only OS trees via HTTP, and where the OS includes (if desired) an entirely separate mechanism to install applications, stored in /var if they’re system global, or /home for per-user application installation. An example application mechanism is http://docker.io/ . However, it is entirely possible to use OSTree underneath a package system, where the contents of /usr are computed on the client. For example, when installing a package, rather than changing the currently running filesystem, the package manager could assemble a new filesystem tree that layers the new packages on top of a base tree, record it in the local OSTree repository, and then set it up for the next boot. To support this model, OSTree provides an (introspectable) C shared library. ", + "url": "/ostree/introduction/#comparison-with-package-managers", + + "relUrl": "/introduction/#comparison-with-package-managers" + },"101": { + "doc": "OSTree Overview", + "title": "Comparison with block/image replication", + "content": "OSTree shares some similarity with “dumb” replication and stateless deployments, such as the model common in “cloud” deployments where nodes are booted from an (effectively) readonly disk, and user data is kept on a different volumes. The advantage of “dumb” replication, shared by both OSTree and the cloud model, is that it’s reliable and predictable. But unlike many default image-based deployments, OSTree supports exactly two persistent writable directories that are preserved across upgrades: /etc and /var. Because OSTree operates at the Unix filesystem layer, it works on top of any filesystem or block storage layout; it’s possible to replicate a given filesystem tree from an OSTree repository into plain ext4, BTRFS, XFS, or in general any Unix-compatible filesystem that supports hard links. Note: OSTree will transparently take advantage of some BTRFS features if deployed on it. OSTree is orthogonal to virtualization mechanisms like AMIs and qcow2 images, though it’s most useful though if you plan to update stateful VMs in-place, rather than generating new images. In practice, users of “bare metal” configurations will find the OSTree model most useful. ", + "url": "/ostree/introduction/#comparison-with-blockimage-replication", + + "relUrl": "/introduction/#comparison-with-blockimage-replication" + },"102": { + "doc": "OSTree Overview", + "title": "Atomic transitions between parallel-installable read-only filesystem trees", + "content": "Another deeply fundamental difference between both package managers and image-based replication is that OSTree is designed to parallel-install multiple versions of multiple independent operating systems. OSTree relies on a new toplevel ostree directory; it can in fact parallel install inside an existing OS or distribution occupying the physical / root. On each client machine, there is an OSTree repository stored in /ostree/repo, and a set of “deployments” stored in /ostree/deploy/$STATEROOT/$CHECKSUM. Each deployment is primarily composed of a set of hardlinks into the repository. This means each version is deduplicated; an upgrade process only costs disk space proportional to the new files, plus some constant overhead. The model OSTree emphasizes is that the OS read-only content is kept in the classic Unix /usr; it comes with code to create a Linux read-only bind mount to prevent inadvertent corruption. There is exactly one /var writable directory shared between each deployment for a given OS. The OSTree core code does not touch content in this directory; it is up to the code in each operating system for how to manage and upgrade state. Finally, each deployment has its own writable copy of the configuration store /etc. On upgrade, OSTree will perform a basic 3-way diff, and apply any local changes to the new copy, while leaving the old untouched. ", + "url": "/ostree/introduction/#atomic-transitions-between-parallel-installable-read-only-filesystem-trees", + + "relUrl": "/introduction/#atomic-transitions-between-parallel-installable-read-only-filesystem-trees" + },"103": { + "doc": "Related Projects", + "title": "Related Projects", + "content": ". | Combining dpkg/rpm + (BTRFS/LVM) | ChromiumOS updater | Ubuntu Image Based Updates | Clear Linux Software update | casync | Mender.io | OLPC update | NixOS / Nix | Solaris IPS | Google servers (custom rsync-like approach, live updates) | Conary | bmap | Git | Conda | rpm-ostree | GNOME Continuous | Docker | Docker-related: Balena | Torizon Platform . | Torizon OS | TorizonCore Builder | Torizon Cloud | . | . OSTree is in many ways very evolutionary. It builds on concepts and ideas introduced from many different projects such as Systemd Stateless, Systemd Bootloader Spec, Chromium Autoupdate, the much older Fedora/Red Hat Stateless Project, Linux VServer and many more. As mentioned elsewhere, OSTree is strongly influenced by package manager designs as well. This page is not intended to be an exhaustive list of such projects, but we will try to keep it up to date, and relatively agnostic. Broadly speaking, projects in this area fall into two camps; either a tool to snapshot systems on the client side (dpkg/rpm + BTRFS/LVM), or a tool to compose on a server and replicate (ChromiumOS, Clear Linux). OSTree is flexible enough to do both. Note that this section of the documentation is almost entirely focused on the “ostree for host” model; the flatpak project uses libostree to store application data, distinct from the host system management model. ", + "url": "/ostree/related-projects/", + + "relUrl": "/related-projects/" + },"104": { + "doc": "Related Projects", + "title": "Combining dpkg/rpm + (BTRFS/LVM)", + "content": "In this approach, one uses a block/filesystem snapshot tool underneath the system package manager. The oVirt Node imgbased tool is an example of this approach, as are a few others below. Regarding BTRFS in particular - the OSTree author believes that Linux storage is a wide world, and while BTRFS is quite good, it is not everywhere now, nor will it be in the near future. There are other recently developed filesystems like f2fs, and Red Hat Enterprise Linux still defaults to XFS. Using a snapshot tool underneath a package manager does help significantly. In the rest of this text, we will use “BTRFS” as a mostly generic tool for filesystem snapshots. The obvious thing to do is layer BTRFS under dpkg/rpm, and have a separate subvolume for /home so rollbacks don’t lose your data. See e.g. Fedora BTRFS Rollback Feature. More generally, if you want to use BTRFS to roll back changes made by dpkg/rpm, you have to carefully set up the partition layout so that the files laid out by dpkg/rpm are installed in a subvolume to snapshot. This problem in many ways is addressed by the changes OSTree forces, such as putting all local state in /var (e.g. /usr/local -> /var/usrlocal). Then one can BTRFS snapshot /usr. This gets pretty far, except handling /etc is messy. This is something OSTree does well. In general, if one really tries to flesh out the BTRFS approach, a nontrivial middle layer of code between dpkg/rpm and BTRFS (or deep awareness of BTRFS in dpkg/rpm itself) will be required. A good example of this is the snapper.io project. The OSTree author believes that having total freedom at the block storage layer is better for general purpose operating systems. For example, the ability to choose dm-crypt per deployment is quite useful; not every site wants to pay the performance penalty. One can choose LVM or not, etc. Where applicable, OSTree does take advantage of copy-on-write/reflink features offered by the kernel for /etc. It uses the now generic ioctl(FICLONE) and copy_file_range(). Another major distinction between the default OSTree usage and package managers is whether updates are “online” or “offline” by default. The default OSTree design writes updates into a new root, leaving the running system unchanged. This means preparing updates is completely non-disruptive and safe - if the system runs out of disk space in the middle, it’s easy to recover. However, there is work in the rpm-ostree project to support online updates as well. OSTree supports using “bare-user” repositories, which do not require root to use. Using a filesystem-level layer without root is more difficult and would likely require a setuid helper or privileged service. Finally, see the next portion around ChromiumOS for why a hybrid but integrated package/image system improves on this. ", + "url": "/ostree/related-projects/#combining-dpkgrpm--btrfslvm", + + "relUrl": "/related-projects/#combining-dpkgrpm--btrfslvm" + },"105": { + "doc": "Related Projects", + "title": "ChromiumOS updater", + "content": "Many people who look at OSTree are most interested in using it as an updater for embedded or fixed-purpose systems, similar to use cases from the ChromiumOS updater. The ChromiumOS approach uses two partitions that are swapped via the bootloader. It has a very network-efficient update protocol, using a custom binary delta scheme between filesystem snapshots. This model even allows for switching filesystem types in an update. A major downside of this approach is that the OS size is doubled on disk always. In contrast, OSTree uses plain Unix hardlinks, which means it essentially only requires disk space proportional to the changed files, plus some small fixed overhead. This means with OSTree, one can easily have more than two trees (deployments). Another example is that the system OSTree repository could also be used for application containers. Finally, the author of OSTree believes that what one really wants for many cases is image replication with the ability to layer on some additional components (e.g. packages) - a hybrid model. This is what rpm-ostree is aiming to support. ", + "url": "/ostree/related-projects/#chromiumos-updater", + + "relUrl": "/related-projects/#chromiumos-updater" + },"106": { + "doc": "Related Projects", + "title": "Ubuntu Image Based Updates", + "content": "See https://wiki.ubuntu.com/ImageBasedUpgrades. Very architecturally similar to ChromeOS, although more interesting is discussion for supporting package installation on top, similar to rpm-ostree package layering. ", + "url": "/ostree/related-projects/#ubuntu-image-based-updates", + + "relUrl": "/related-projects/#ubuntu-image-based-updates" + },"107": { + "doc": "Related Projects", + "title": "Clear Linux Software update", + "content": "The Clear Linux Software update system is not very well documented. This mailing list post has some reverse-engineered design documentation. Like OSTree static deltas, it also uses bsdiff for network efficiency. More information will be filled in here over time. The OSTree author believes that at the moment, the “CL updater” is not truly atomic in the sense that because it applies updates live, there is a window where the OS root may be inconsistent. ", + "url": "/ostree/related-projects/#clear-linux-software-update", + + "relUrl": "/related-projects/#clear-linux-software-update" + },"108": { + "doc": "Related Projects", + "title": "casync", + "content": "The systemd casync project is relatively new. Currently, it is more of a storage library, and doesn’t support higher level logic for things like GPG signatures, versioning information, etc. This is mostly the OstreeRepo layer. Moving up to the OstreeSysroot level - things like managing the bootloader configuration, and most importantly implementing correct merging for /etc are missing. casync also is unaware of SELinux. OSTree is really today a shared library, and has been for quite some time. This has made it easy to build higher level projects such as rpm-ostree which has quite a bit more, such as a DBus API and other projects consume that, such as Cockpit. A major issue with casync today is that it doesn’t support garbage collection on the server side. OSTree’s GC works symmetrically on the server and client side. Broadly speaking, casync is a twist on the dual partition approach, and shares the general purpose disadvantages of those. ", + "url": "/ostree/related-projects/#casync", + + "relUrl": "/related-projects/#casync" + },"109": { + "doc": "Related Projects", + "title": "Mender.io", + "content": "Mender.io is another implementation of the dual partition approach. ", + "url": "/ostree/related-projects/#menderio", + + "relUrl": "/related-projects/#menderio" + },"110": { + "doc": "Related Projects", + "title": "OLPC update", + "content": "OSTree is basically a generalization of olpc-update, except using plain HTTP instead of rsync. OSTree has the notion of separate trees that one can track independently or parallel install, while still sharing storage via the hardlinked repository, whereas olpc-update uses version numbers for a single OS. OSTree has built-in plain old HTTP replication which can be served from a static webserver, whereas olpc-update uses rsync (more server load, but more efficient on the network side). The OSTree solution to improving network bandwidth consumption is via static deltas. See this comment for a comparison. ", + "url": "/ostree/related-projects/#olpc-update", + + "relUrl": "/related-projects/#olpc-update" + },"111": { + "doc": "Related Projects", + "title": "NixOS / Nix", + "content": "See NixOS. It was a very influential project for OSTree. NixOS and OSTree both support the idea of independent “roots” that are bootable. In NixOS, files in a package are accessed by a path depending on the checksums of package inputs (build dependencies) - see Nix store. However, OSTree uses a commit/deploy model - it isn’t tied to any particular directory layout, and you can put whatever data you want inside an OSTree, for example the standard FHS layout. A both positive and negative of the Nix model is that a change in the build dependencies (e.g. being built with a newer gcc), requires a cascading rebuild of everything. It’s good because it makes it easy to do massive system-wide changes such as gcc upgrades, and allows installing multiple versions of packages at once. However, a security update to e.g. glibc forces a rebuild of everything from scratch, and so Nix is not practical at scale. OSTree supports using a build system that just rebuilds individual components (packages) as they change, without forcing a rebuild of their dependencies. Nix automatically detects runtime package dependencies by scanning content for hashes. OSTree only supports only system-level images, and doesn’t do dependency management. Nix can store arbitrary files, using nix-store --add, but, more commonly, paths are added as the result of running a derivation file generated using the Nix language. OSTree is build-system agnostic; filesystem trees are committed using a simple C API, and this is the only way to commit files. OSTree automatically shares the storage of identical data using hard links into a content-addressed store. Nix can deduplicate using hard links as well, using the auto-optimise-store option, but this is not on by default, and Nix does not guarantee that all of its files are in the content-addressed store. OSTree provides a git-like command line interface for browsing the content-addressed store, while Nix does not have this functionality. Nix used to use the immutable bit to prevent modifications to /nix/store, but now it uses a read-only bind mount. The bind mount can be privately remounted, allowing per-process privileged write access. OSTree uses the immutable bit on the root of the deployment, and mounts /usr as read-only. NixOS supports switching OS images on-the-fly, by maintaining both booted-system and current-system roots. It is not clear how well this approach works. OSTree currently requries a reboot to switch images. Finally, NixOS supports installing user-specific packages from trusted repositories without requiring root, using a trusted daemon. Flatpak, based on OSTree, similarly has a policykit-based system helper that allows you to authenticate via polkit to install into the system repository. ", + "url": "/ostree/related-projects/#nixos--nix", + + "relUrl": "/related-projects/#nixos--nix" + },"112": { + "doc": "Related Projects", + "title": "Solaris IPS", + "content": "See Solaris IPS. Broadly, this is a similar design as to a combination of BTRFS+RPM/deb. There is a bootloader management system which combines with the snapshots. It’s relatively well thought through - however, it is a client-side system assembly. If one wants to image servers and replicate reliably, that’d be a different system. ", + "url": "/ostree/related-projects/#solaris-ips", + + "relUrl": "/related-projects/#solaris-ips" + },"113": { + "doc": "Related Projects", + "title": "Google servers (custom rsync-like approach, live updates)", + "content": "This paper talks about how Google was (at least at one point) managing updates for the host systems for some servers: Live Upgrading Thousands of Servers from an Ancient Red Hat Distribution to 10 Year Newer Debian Based One (USENIX LISA 2013) . ", + "url": "/ostree/related-projects/#google-servers-custom-rsync-like-approach-live-updates", + + "relUrl": "/related-projects/#google-servers-custom-rsync-like-approach-live-updates" + },"114": { + "doc": "Related Projects", + "title": "Conary", + "content": "See Conary Updates and Rollbacks. If rpm/dpkg are like CVS, Conary is closer to Subversion. It’s not bad, but e.g. its rollback model is rather ad-hoc and not atomic. It also is a fully client side system and doesn’t have an image-like replication with deltas. ", + "url": "/ostree/related-projects/#conary", + + "relUrl": "/related-projects/#conary" + },"115": { + "doc": "Related Projects", + "title": "bmap", + "content": "See bmap. A tool for optimized copying of disk images. Intended for offline use, so not directly comparable. ", + "url": "/ostree/related-projects/#bmap", + + "relUrl": "/related-projects/#bmap" + },"116": { + "doc": "Related Projects", + "title": "Git", + "content": "Although OSTree has been called “Git for Binaries”, and the two share the idea of a hashed content store, the implementation details are quite different. OSTree supports extended attributes and uses SHA256 instead of Git’s SHA1. It “checks out” files via hardlinks, rather than copying, and thus requires the checkout to be immutable. At the moment, OSTree commits may have at most one parent, as opposed to Git which allows an arbitrary number. Git uses a smart-delta protocol for updates, while OSTree uses 1 HTTP request per changed file, or can generate static deltas. ", + "url": "/ostree/related-projects/#git", + + "relUrl": "/related-projects/#git" + },"117": { + "doc": "Related Projects", + "title": "Conda", + "content": "Conda is an “OS-agnostic, system-level binary package manager and ecosystem”; although most well-known for its accompanying Python distribution anaconda, its scope has been expanding quickly. The package format is very similar to well-known ones such as RPM. However, unlike typical RPMs, the packages are built to be relocatable. Also, the package manager runs natively on Windows. Conda’s main advantage is its ability to install collections of packages into “environments” by unpacking them all to the same directory. Conda reduces duplication across environments using hardlinks, similar to OSTree’s sharing between deployments (although Conda uses package / file path instead of file hash). Overall, it is quite similar to rpm-ostree in functionality and scope. ", + "url": "/ostree/related-projects/#conda", + + "relUrl": "/related-projects/#conda" + },"118": { + "doc": "Related Projects", + "title": "rpm-ostree", + "content": "This builds on top of ostree to support building RPMs into OSTree images, and even composing RPMs on-the-fly using an overlay filesystem. It is being developed by Fedora, Red Hat, and CentOS as part of Project Atomic. ", + "url": "/ostree/related-projects/#rpm-ostree", + + "relUrl": "/related-projects/#rpm-ostree" + },"119": { + "doc": "Related Projects", + "title": "GNOME Continuous", + "content": "This is a service that incrementally rebuilds and tests GNOME on every commit. The need to make and distribute snapshots for this system was the original inspiration for ostree. ", + "url": "/ostree/related-projects/#gnome-continuous", + + "relUrl": "/related-projects/#gnome-continuous" + },"120": { + "doc": "Related Projects", + "title": "Docker", + "content": "It makes sense to compare OSTree and Docker as far as wire formats go. OSTree is not itself a container tool, but can be used as a transport/storage format for container tools. Docker has (at the time of this writing) two format versions (v1 and v2). v1 is deprecated, so we’ll look at format version 2. A Docker image is a series of layers, and a layer is essentially JSON metadata plus a tarball. The tarballs capture changes between layers, including handling deleting files in higher layers. Because the payload format is just tar, Docker hence captures (numeric) uid/gid and xattrs. This “layering” model is an interesting and powerful part of Docker, allowing different images to reference a shared base. OSTree doesn’t implement this natively, but it’s not difficult to implement in higher level tools. For example in flatpak, there’s a concept of a SDK and runtime, and it would make a lot of sense for the SDK to depend on the runtime, to avoid clients downloading data twice (even if it’s deduplicated on disk). That gets to an advantage of OSTree over Docker; OSTree checksums individual files (not tarballs), and uses this for deduplication. Docker (natively) only shares storage via layering. The biggest feature OSTree has over Docker though is support for (static) deltas, and even without pre-configured static deltas, the archive format has “natural” deltas. Particularly for a “base operating system”, one really wants on-wire deltas. It’d likely be possible to extend Docker with this concept. A core challenge both share is around metadata (particularly signing) and search/discovery (the ostree summary file doesn’t scale very well). One major issue Docker has is that it checksums compressed data, and furthermore the tar format is flexible, with multiple ways to represent data, making it hard to impossible to reassemble and verify from on-disk state. The tarsum effort was intended to address this, but it was not adopted in the end for v2. ", + "url": "/ostree/related-projects/#docker", + + "relUrl": "/related-projects/#docker" + },"121": { + "doc": "Related Projects", + "title": "Docker-related: Balena", + "content": "The Balena project forks Docker and aims to even use Docker/OCI format for the root filesystem, and adds wire deltas using librsync. See also discussion on libostree-list. ", + "url": "/ostree/related-projects/#docker-related-balena", + + "relUrl": "/related-projects/#docker-related-balena" + },"122": { + "doc": "Related Projects", + "title": "Torizon Platform", + "content": "Torizon is an open-source software platform that simplifies the development and maintenance of embedded Linux software. It is designed to be used out-of-the-box on devices requiring high reliability, allowing you to focus on your application and not on building and maintaining the operating system. Torizon OS . The platform OS - Torizon OS - is a minimal OS with a Docker runtime and libostree + Aktualizr. The main goal of this system is to allow application developers to use containers, while the maintainers of Torizon OS focus on the base system updates. TorizonCore Builder . Since the Torizon OS is meant as a binary distribution, OS customization is made easier with TorizonCore Builder, as the tool abstracts the handling of OSTree concepts from the final users. Torizon Cloud . Torizon Cloud is a hosted OTA update system that provides OS updates to Torizon OS using OSTree and Aktualizr. ", + "url": "/ostree/related-projects/#torizon-platform", + + "relUrl": "/related-projects/#torizon-platform" + },"123": { + "doc": "Anatomy of an OSTree repository", + "title": "Anatomy of an OSTree repository", + "content": ". | Core object types and data model . | Commit objects | Dirtree objects | Dirmeta objects | Content objects | Xattrs objects | . | Repository types and locations . | Refs | The summary file | . | . ", + "url": "/ostree/repo/", + + "relUrl": "/repo/" + },"124": { + "doc": "Anatomy of an OSTree repository", + "title": "Core object types and data model", + "content": "OSTree is deeply inspired by git; the core layer is a userspace content-addressed versioning filesystem. It is worth taking some time to familiarize yourself with Git Internals, as this section will assume some knowledge of how git works. Its object types are similar to git; it has commit objects and content objects. Git has “tree” objects, whereas OSTree splits them into “dirtree” and “dirmeta” objects. But unlike git, OSTree’s checksums are SHA256. And most crucially, its content objects include uid, gid, and extended attributes (but still no timestamps). Commit objects . A commit object contains metadata such as a timestamp, a log message, and most importantly, a reference to a dirtree/dirmeta pair of checksums which describe the root directory of the filesystem. Also like git, each commit in OSTree can have a parent. It is designed to store a history of your binary builds, just like git stores a history of source control. However, OSTree also makes it easy to delete data, under the assumption that you can regenerate it from source code. Dirtree objects . A dirtree contains a sorted array of (filename, checksum) pairs for content objects, and a second sorted array of (filename, dirtree checksum, dirmeta checksum), which are subdirectories. This type of object is stored as files ending with .dirtree in the objects directory. Dirmeta objects . In git, tree objects contain the metadata such as permissions for their children. But OSTree splits this into a separate object to avoid duplicating extended attribute listings. These type of objects are stored as files ending with .dirmeta in the objects directory. Content objects . Unlike the first three object types which are metadata, designed to be mmap()ed, the content object has a separate internal header and payload sections. The header contains uid, gid, mode, and symbolic link target (for symlinks), as well as extended attributes. After the header, for regular files, the content follows. These parts together form the SHA256 hash for content objects. The content type objects in this format exist only in archive OSTree repositories. Today the content part is gzip’ed and the objects are stored as files ending with .filez in the objects directory. Because the SHA256 hash is formed over the uncompressed content, these files do not match the hash they are named as. The OSTree data format intentionally does not contain timestamps. The reasoning is that data files may be downloaded at different times, and by different build systems, and so will have different timestamps but identical physical content. These files may be large, so most users would like them to be shared, both in the repository and between the repository and deployments. This could cause problems with programs that check if files are out-of-date by comparing timestamps. For Git, the logical choice is to not mess with timestamps, because unnecessary rebuilding is better than a broken tree. However, OSTree has to hardlink files to check them out, and commits are assumed to be internally consistent with no build steps needed. For this reason, OSTree acts as though all timestamps are set to time_t 0, so that comparisons will be considered up-to-date. Note that for a few releases, OSTree used 1 to fix warnings such as GNU Tar emitting “implausibly old time stamp” with 0; however, until we have a mechanism to transition cleanly to 1, for compatibilty OSTree is reverted to use zero again. Xattrs objects . In some repository modes (e.g. bare-split-xattrs), xattrs are stored on the side of the content objects they refer to. This is done via two dedicated object types, file-xattrs and file-xattrs-link. file-xattrs store xattrs data, encoded as GVariant. Each object is keyed by the checksum of the xattrs content, allowing for multiple references. file-xattrs-link are hardlinks which are associated to file objects. Each object is keyed by the same checksum of the corresponding file object. The target of the hardlink is an existing file-xattrs object. In case of reaching the limit of too many links, this object could be a plain file too. ", + "url": "/ostree/repo/#core-object-types-and-data-model", + + "relUrl": "/repo/#core-object-types-and-data-model" + },"125": { + "doc": "Anatomy of an OSTree repository", + "title": "Repository types and locations", + "content": "Also unlike git, an OSTree repository can be in one of five separate modes: bare, bare-split-xattrs, bare-user, bare-user-only, and archive. A bare repository is one where content files are just stored as regular files; it’s designed to be the source of a “hardlink farm”, where each operating system checkout is merely links into it. If you want to store files owned by e.g. root in this mode, you must run OSTree as root. The bare-split-xattrs mode is similar to the above one, but it does store xattrs as separate objects. This is meant to avoid conflicts with kernel-enforced constraints (e.g. on SELinux labels) and with other softwares that may perform ephemeral changes to xattrs (e.g. container runtimes). The bare-user mode is a later addition that is like bare in that files are unpacked, but it can (and should generally) be created as non-root. In this mode, extended metadata such as owner uid, gid, and extended attributes are stored in extended attributes under the name user.ostreemeta but not actually applied. The bare-user mode is useful for build systems that run as non-root but want to generate root-owned content, as well as non-root container systems. The bare-user-only mode is a variant to the bare-user mode. Unlike bare-user, neither ownership nor extended attributes are stored. These repos are meant to to be checked out in user mode (with the -U flag), where this information is not applied anyway. Hence this mode may lose metadata. The main advantage of bare-user-only is that repos can be stored on filesystems which do not support extended attributes, such as tmpfs. In contrast, the archive mode is designed for serving via plain HTTP. Like tar files, it can be read/written by non-root users. On an OSTree-deployed system, the “system repository” is /ostree/repo. It can be read by any uid, but only written by root. The ostree command will by default operate on the system repository; you may provide the --repo argument to override this, or set the $OSTREE_REPO environment variable. ", + "url": "/ostree/repo/#repository-types-and-locations", + + "relUrl": "/repo/#repository-types-and-locations" + },"126": { + "doc": "Anatomy of an OSTree repository", + "title": "Refs", + "content": "Like git, OSTree uses the terminology “references” (abbreviated “refs”) which are text files that name (refer to) particular commits. See the Git Documentation for information on how git uses them. Unlike git though, it doesn’t usually make sense to have a “main” branch. There is a convention for references in OSTree that looks like this: exampleos/buildmain/x86_64-runtime and exampleos/buildmain/x86_64-devel-debug. These two refs point to two different generated filesystem trees. In this example, the “runtime” tree contains just enough to run a basic system, and “devel-debug” contains all of the developer tools and debuginfo. The ostree supports a simple syntax using the caret ^ to refer to the parent of a given commit. For example, exampleos/buildmain/x86_64-runtime^ refers to the previous build, and exampleos/buildmain/x86_64-runtime^^ refers to the one before that. ", + "url": "/ostree/repo/#refs", + + "relUrl": "/repo/#refs" + },"127": { + "doc": "Anatomy of an OSTree repository", + "title": "The summary file", + "content": "A later addition to OSTree is the concept of a “summary” file, created via the ostree summary -u command. This was introduced for a few reasons. A primary use case is to be compatible with Metalink, which requires a single file with a known checksum as a target. The summary file primarily contains two mappings: . | A mapping of the refs and their checksums, equivalent to fetching the ref file individually | A list of all static deltas, along with their metadata checksums | . This currently means that it grows linearly with both items. On the other hand, using the summary file, a client can enumerate branches. Further, fetching the summary file over e.g. pinned TLS creates a strong end-to-end verification of the commit or static delta. The summary file can also be GPG signed (detached). This is currently the only way to provide GPG signatures (transitively) on deltas. If a repository administrator creates a summary file, they must thereafter run ostree summary -u to update it whenever a ref is updated or a static delta is generated. ", + "url": "/ostree/repo/#the-summary-file", + + "relUrl": "/repo/#the-summary-file" + },"128": { + "doc": "Managing content in OSTree repositories", + "title": "Managing content in OSTree repositories", + "content": ". | Mirroring repositories | Separate development vs release repositories | Promoting content along OSTree branches - “buildmain”, “smoketested” | Promoting content between OSTree repositories | Derived data - static deltas and the summary file | Pruning our build and dev repositories | Generating “scratch” deltas for efficient initial downloads | . Once you have a build system going, if you actually want client systems to retrieve the content, you will quickly feel a need for “repository management”. The command line tool ostree does cover some core functionality, but doesn’t include very high level workflows. One reason is that how content is delivered and managed has concerns very specific to the organization. For example, some operating system content vendors may want integration with a specific errata notification system when generating commits. In this section, we will describe some high level ideas and methods for managing content in OSTree repositories, mostly independent of any particular model or tool. That said, there is an associated upstream project ostree-releng-scripts which has some scripts that are intended to implement portions of this document. Another example of software which can assist in managing OSTree repositories today is the Pulp Project, which has a Pulp OSTree plugin. ", + "url": "/ostree/repository-management/", + + "relUrl": "/repository-management/" + },"129": { + "doc": "Managing content in OSTree repositories", + "title": "Mirroring repositories", + "content": "It’s very common to want to perform a full or partial mirror, in particular across organizational boundaries (e.g. an upstream OS provider, and a user that wants offline and faster access to the content). OSTree supports both full and partial mirroring of the base archive content, although not yet of static deltas. To create a mirror, first create an archive repository (you don’t need to run this as root), then add the upstream as a remote, then use pull --mirror. ostree --repo=repo init --mode=archive ostree --repo=repo remote add exampleos https://exampleos.com/ostree/repo ostree --repo=repo pull --mirror exampleos:exampleos/x86_64/standard . You can use the --depth=-1 option to retrieve all history, or a positive integer like 3 to retrieve just the last 3 commits. See also the rsync-repos script in ostree-releng-scripts. ", + "url": "/ostree/repository-management/#mirroring-repositories", + + "relUrl": "/repository-management/#mirroring-repositories" + },"130": { + "doc": "Managing content in OSTree repositories", + "title": "Separate development vs release repositories", + "content": "By default, OSTree accumulates server side history. This is actually optional in that your build system can (using the API) write a commit with no parent. But first, we’ll investigate the ramifications of server side history. Many content vendors will want to separate their internal development with what is made public to the world. Therefore, you will want (at least) two OSTree repositories, we’ll call them “dev” and “prod”. To phrase this another way, let’s say you have a continuous delivery system which is building from git and committing into your “dev” OSTree repository. This might happen tens to hundreds of times per day. That’s a substantial amount of history over time, and it’s unlikely most of your content consumers (i.e. not developers/testers) will be interested in all of it. The original vision of OSTree was to fulfill this “dev” role, and in particular the “archive” format was designed for it. Then, what you’ll want to do is promote content from “dev” to “prod”. We’ll discuss this later, but first, let’s talk about promotion inside our “dev” repository. ", + "url": "/ostree/repository-management/#separate-development-vs-release-repositories", + + "relUrl": "/repository-management/#separate-development-vs-release-repositories" + },"131": { + "doc": "Managing content in OSTree repositories", + "title": "Promoting content along OSTree branches - “buildmain”, “smoketested”", + "content": "Besides multiple repositories, OSTree also supports multiple branches inside one repository, equivalent to git’s branches. We saw in an earlier section an example branch name like exampleos/x86_64/standard. Choosing the branch name for your “prod” repository is absolutely critical as client systems will reference it. It becomes an important part of your face to the world, in the same way the “main” branch in a git repository is. But with your “dev” repository internally, it can be very useful to use OSTree’s branching concepts to represent different stages in a software delivery pipeline. Deriving from exampleos/x86_64/standard, let’s say our “dev” repository contains exampleos/x86_64/buildmain/standard. We choose the term “buildmain” to represent something that came straight from git main. It may not be tested very much. Our next step should be to hook up a testing system (Jenkins, Buildbot, etc.) to this. When a build (commit) passes some tests, we want to “promote” that commit. Let’s create a new branch called smoketested to say that some basic sanity checks pass on the complete system. This might be where human testers get involved, for example. This is a basic way to “promote” the buildmain commit that passed testing: . ostree commit -b exampleos/x86_64/smoketested/standard -s 'Passed tests' --tree=ref=aec070645fe53... Here we’re generating a new commit object (perhaps include in the commit log links to build logs, etc.), but we’re reusing the content from the buildmain commit aec070645fe53 that passed the smoketests. For a more sophisticated implementation of this model, see the do-release-tags script, which includes support for things like propagating version numbers across commit promotion. We can easily generalize this model to have an arbitrary number of stages like exampleos/x86_64/stage-1-pass/standard, exampleos/x86_64/stage-2-pass/standard, etc. depending on business requirements and logic. In this suggested model, the “stages” are increasingly expensive. The logic is that we don’t want to spend substantial time on e.g. network performance tests if something basic like a systemd unit file fails on bootup. ", + "url": "/ostree/repository-management/#promoting-content-along-ostree-branches---buildmain-smoketested", + + "relUrl": "/repository-management/#promoting-content-along-ostree-branches---buildmain-smoketested" + },"132": { + "doc": "Managing content in OSTree repositories", + "title": "Promoting content between OSTree repositories", + "content": "Now, we have our internal continuous delivery stream flowing, it’s being tested and works. We want to periodically take the latest commit on exampleos/x86_64/stage-3-pass/standard and expose it in our “prod” repository as exampleos/x86_64/standard, with a much smaller history. We’ll have other business requirements such as writing release notes (and potentially putting them in the OSTree commit message), etc. In Build Systems we saw how the pull-local command can be used to migrate content from the “build” repository (in bare-user mode) into an archive repository for serving to client systems. Following this section, we now have three repositories, let’s call them repo-build, repo-dev, and repo-prod. We’ve been pulling content from repo-build into repo-dev (which involves gzip compression among other things since it is a format change). When using pull-local to migrate content between two archive repositories, the binary content is taken unmodified. Let’s go ahead and generate a new commit in our prod repository: . checksum=$(ostree --repo=repo-dev rev-parse exampleos/x86_64/stage-3-pass/standard`) ostree --repo=repo-prod pull-local repo-dev ${checksum} ostree --repo=repo-prod commit -b exampleos/x86_64/standard \\ -s 'Release 1.2.3' --add-metadata-string=version=1.2.3 \\ --tree=ref=${checksum} . There are a few things going on here. First, we found the latest commit checksum for the “stage-3 dev”, and told pull-local to copy it, without using the branch name. We do this because we don’t want to expose the exampleos/x86_64/stage-3-pass/standard branch name in our “prod” repository. Next, we generate a new commit in prod that’s referencing the exact binary content in dev. If the “dev” and “prod” repositories are on the same Unix filesystem, (like git) OSTree will make use of hard links to avoid copying any content at all - making the process very fast. Another interesting thing to notice here is that we’re adding an version metadata string to the commit. This is an optional piece of metadata, but we are encouraging its use in the OSTree ecosystem of tools. Commands like ostree admin status show it by default. ", + "url": "/ostree/repository-management/#promoting-content-between-ostree-repositories", + + "relUrl": "/repository-management/#promoting-content-between-ostree-repositories" + },"133": { + "doc": "Managing content in OSTree repositories", + "title": "Derived data - static deltas and the summary file", + "content": "As discussed in Formats, the archive repository we use for “prod” requires one HTTP fetch per client request by default. If we’re only performing a release e.g. once a week, it’s appropriate to use “static deltas” to speed up client updates. So once we’ve used the above command to pull content from repo-dev into repo-prod, let’s generate a delta against the previous commit: . ostree --repo=repo-prod static-delta generate exampleos/x86_64/standard . We may also want to support client systems upgrading from two commits previous. ostree --repo=repo-prod static-delta generate --from=exampleos/x86_64/standard^^ --to=exampleos/x86_64/standard . Generating a full permutation of deltas across all prior versions can get expensive, and there is some support in the OSTree core for static deltas which “recurse” to a parent. This can help create a model where clients download a chain of deltas. Support for this is not fully implemented yet however. Regardless of whether or not you choose to generate static deltas, you should update the summary file: . ostree --repo=repo-prod summary -u . (Remember, the summary command cannot be run concurrently, so this should be triggered serially by other jobs). There is some more information on the design of the summary file in Repo. ", + "url": "/ostree/repository-management/#derived-data---static-deltas-and-the-summary-file", + + "relUrl": "/repository-management/#derived-data---static-deltas-and-the-summary-file" + },"134": { + "doc": "Managing content in OSTree repositories", + "title": "Pruning our build and dev repositories", + "content": "First, the OSTree author believes you should not use OSTree as a “primary content store”. The binaries in an OSTree repository should be derived from a git repository. Your build system should record proper metadata such as the configuration options used to generate the build, and you should be able to rebuild it if necessary. Art assets should be stored in a system that’s designed for that (e.g. Git LFS). Another way to say this is that five years down the line, we are unlikely to care about retaining the exact binaries from an OS build on Wednesday afternoon three years ago. We want to save space and prune our “dev” repository. ostree --repo=repo-dev prune --refs-only --keep-younger-than=\"6 months ago\" . That will truncate the history older than 6 months. Deleted commits will have “tombstone markers” added so that you know they were explicitly deleted, but all content in them (that is not referenced by a still retained commit) will be garbage collected. ", + "url": "/ostree/repository-management/#pruning-our-build-and-dev-repositories", + + "relUrl": "/repository-management/#pruning-our-build-and-dev-repositories" + },"135": { + "doc": "Managing content in OSTree repositories", + "title": "Generating “scratch” deltas for efficient initial downloads", + "content": "In general, the happy path for OSTree downloads is via static deltas. If you are in a situation where you want to download an OSTree commit from an uninitialized repo (or one with unrelated history), you can generate “scratch” (aka --empty deltas) which bundle all objects for that commit. The tradeoff here is increasing server disk space in return for many fewer client HTTP requests. For example: . $ ostree --repo=/path/to/repo static-delta generate --empty --to=exampleos/x86_64/testing-devel $ ostree --repo=/path/to/repo summary -u . After that, clients fetching that commit will prefer fetching the “scratch” delta if they don’t have the original ref. ", + "url": "/ostree/repository-management/#generating-scratch-deltas-for-efficient-initial-downloads", + + "relUrl": "/repository-management/#generating-scratch-deltas-for-efficient-initial-downloads" + },"136": { + "doc": "OSTree and /var handling", + "title": "OSTree and /var handling", + "content": ". | OSTree and /var handling . | Default commit/image /var handling | Pitfalls | Examples . | debs/RPMs which drop files into /opt (i.e. /var/opt) | Apache default content in /var/www/html | User home directories and databases | /var/lib/containers | dnf /var/lib/dnf/history.sqlite | . | Previous ostree /var and tmpfiles.d /usr/share/factory/var | . | . ", + "url": "/ostree/var/", + + "relUrl": "/var/" + },"137": { + "doc": "OSTree and /var handling", + "title": "Default commit/image /var handling", + "content": "As of OSTree 2024.3, when a commit is “deployed” (queued to boot), the initial content of /var in a commit will be placed into the “stateroot” (default var) if the stateroot var is empty. The semantics of this are intended to match that of Docker “volumes”; consider that ostree systems have the equivalent of VOLUME /var by default. It is still strongly recommended to use systemd tmpfiles.d snippets to populate directory structure and the like in /var on firstboot, because this is more resilent. Even better, use StateDirectory= for systemd units. ", + "url": "/ostree/var/#default-commitimage-var-handling", + + "relUrl": "/var/#default-commitimage-var-handling" + },"138": { + "doc": "OSTree and /var handling", + "title": "Pitfalls", + "content": "On subsequent upgrades, normally /var would not be empty anymore (as it’s typically expected that basics like /var/tmp etc. are created, if not also other local state such as /var/log etc.). Hence, no updates from the commit/container will be applied. To be clear then: . | Any files which already exist will not be updated. | Any files which are deleted in the new version will not be deleted on existing systems. | . ", + "url": "/ostree/var/#pitfalls", + + "relUrl": "/var/#pitfalls" + },"139": { + "doc": "OSTree and /var handling", + "title": "Examples", + "content": "debs/RPMs which drop files into /opt (i.e. /var/opt) . The default OSTree “strict” layout has /opt be a symlink to /var/opt. Including any packaged content that “straddles” /usr and /var (i.e. /var/opt) will over time cause drift because changes in the package will not be reflected on disk. For situations like this, it’s strongly recommended to enable either composefs.enabled = true or the root.transient = true option for ostree-prepare-root.conf and change ensure your commit/container image has /opt as a plain directory. In the former case, content in /opt will be immutable at runtime, the same as everything else in /usr. In the latter case content it will be writable but transient. There’s also a currently-experimental ../man/ostree-state-overlay@.service.xml which can manage stateful writable overlays for individual mounts. Apache default content in /var/www/html . In general, such static content would much better live in /usr - or even better, in an application container. User home directories and databases . The semantics here are likely OK for the use case of “default users”. /var/lib/containers . Pulling container images into OSTree commits like this would be a bad idea; similar problems as RPM content. dnf /var/lib/dnf/history.sqlite . For $reasons dnf has its own database for state distinct from the RPM database, which on rpm-ostree systems is in /usr/share/rpm (under the read-only bind mount, managed by OS updates). In an image/container-oriented flow, we don’t really care about this database which mainly holds things like “was this package user installed”. This data could move to /usr. ", + "url": "/ostree/var/#examples", + + "relUrl": "/var/#examples" + },"140": { + "doc": "OSTree and /var handling", + "title": "Previous ostree /var and tmpfiles.d /usr/share/factory/var", + "content": "From OSTree versions 2023.8 to v2024.3 the /usr/lib/tmpfiles.d/ostree-tmpfiles.conf file included this snippet: . # Automatically propagate all /var content from /usr/share/factory/var; # the ostree-container stack is being changed to do this, and we want to # encourage ostree use cases in general to follow this pattern. C+! /var - - - - - . Until version 0.13.2 of the ostree-ext project, content in /var in fetched container images is moved to /usr/share/factory/var, but this no longer happens when targeting ostree v2024.3. Together, this will have the semantic that on OS updates, on the next boot (early in boot), any new files/directories will be copied. For more information on this, see man tmpfiles.d. This has been reverted, and the semantics defer to the above ostree semantic. ", + "url": "/ostree/var/#previous-ostree-var-and-tmpfilesd-usrsharefactoryvar", + + "relUrl": "/var/#previous-ostree-var-and-tmpfilesd-usrsharefactoryvar" + } +} diff --git a/assets/js/vendor/lunr.min.js b/assets/js/vendor/lunr.min.js new file mode 100644 index 0000000000..46c594b808 --- /dev/null +++ b/assets/js/vendor/lunr.min.js @@ -0,0 +1,61 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ +/** + * ORIGINAL MIT LICENSE + * Copyright (C) 2013 by Oliver Nightingale + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +!function(){var e,t,r,i,n,s,o,a,u,l,c,h,d,f,p,y,m,g,x,v,w,Q,k,S,E,L,b,P,T=function(e){var t=new T.Builder;return t.pipeline.add(T.trimmer,T.stopWordFilter,T.stemmer),t.searchPipeline.add(T.stemmer),e.call(t,t),t.build()};T.version="2.3.9" +/*! +* lunr.utils +* Copyright (C) 2020 Oliver Nightingale +*/,T.utils={},T.utils.warn=(e=this,function(t){e.console&&console.warn&&console.warn(t)}),T.utils.asString=function(e){return null==e?"":e.toString()},T.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i0){var u=T.utils.clone(t)||{};u.position=[o,a],u.index=n.length,n.push(new T.Token(r.slice(o,s),u))}o=s+1}}return n},T.tokenizer.separator=/[\s\-]+/ +/*! +* lunr.Pipeline +* Copyright (C) 2020 Oliver Nightingale +*/,T.Pipeline=function(){this._stack=[]},T.Pipeline.registeredFunctions=Object.create(null),T.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&T.utils.warn("Overwriting existing registered function: "+t),e.label=t,T.Pipeline.registeredFunctions[e.label]=e},T.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||T.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},T.Pipeline.load=function(e){var t=new T.Pipeline;return e.forEach((function(e){var r=T.Pipeline.registeredFunctions[e];if(!r)throw new Error("Cannot load unregistered function: "+e);t.add(r)})),t},T.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){T.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},T.Pipeline.prototype.after=function(e,t){T.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");r+=1,this._stack.splice(r,0,t)},T.Pipeline.prototype.before=function(e,t){T.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");this._stack.splice(r,0,t)},T.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},T.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e||s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},T.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},T.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var s,o=n.str.charAt(0);o in n.node.edges?s=n.node.edges[o]:(s=new T.TokenSet,n.node.edges[o]=s),1==n.str.length&&(s.final=!0),i.push({node:s,editsRemaining:n.editsRemaining,str:n.str.slice(1)})}if(0!=n.editsRemaining){if("*"in n.node.edges)var a=n.node.edges["*"];else{a=new T.TokenSet;n.node.edges["*"]=a}if(0==n.str.length&&(a.final=!0),i.push({node:a,editsRemaining:n.editsRemaining-1,str:n.str}),n.str.length>1&&i.push({node:n.node,editsRemaining:n.editsRemaining-1,str:n.str.slice(1)}),1==n.str.length&&(n.node.final=!0),n.str.length>=1){if("*"in n.node.edges)var u=n.node.edges["*"];else{u=new T.TokenSet;n.node.edges["*"]=u}1==n.str.length&&(u.final=!0),i.push({node:u,editsRemaining:n.editsRemaining-1,str:n.str.slice(1)})}if(n.str.length>1){var l,c=n.str.charAt(0),h=n.str.charAt(1);h in n.node.edges?l=n.node.edges[h]:(l=new T.TokenSet,n.node.edges[h]=l),1==n.str.length&&(l.final=!0),i.push({node:l,editsRemaining:n.editsRemaining-1,str:c+n.str.slice(2)})}}}return r},T.TokenSet.fromString=function(e){for(var t=new T.TokenSet,r=t,i=0,n=e.length;i=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}} +/*! +* lunr.Index +* Copyright (C) 2020 Oliver Nightingale +*/,T.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},T.Index.prototype.search=function(e){return this.query((function(t){new T.QueryParser(e,t).parse()}))},T.Index.prototype.query=function(e){for(var t=new T.Query(this.fields),r=Object.create(null),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=0;a1?1:e},T.Builder.prototype.k1=function(e){this._k1=e},T.Builder.prototype.add=function(e,t){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=t||{},this.documentCount+=1;for(var n=0;n=this.length)return T.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},T.QueryLexer.prototype.width=function(){return this.pos-this.start},T.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},T.QueryLexer.prototype.backup=function(){this.pos-=1},T.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=T.QueryLexer.EOS&&this.backup()},T.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(T.QueryLexer.TERM)),e.ignore(),e.more())return T.QueryLexer.lexText},T.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(T.QueryLexer.EDIT_DISTANCE),T.QueryLexer.lexText},T.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(T.QueryLexer.BOOST),T.QueryLexer.lexText},T.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(T.QueryLexer.TERM)},T.QueryLexer.termSeparator=T.tokenizer.separator,T.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==T.QueryLexer.EOS)return T.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return T.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(T.QueryLexer.TERM),T.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(T.QueryLexer.TERM),T.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(T.QueryLexer.PRESENCE),T.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(T.QueryLexer.PRESENCE),T.QueryLexer.lexText;if(t.match(T.QueryLexer.termSeparator))return T.QueryLexer.lexTerm}else e.escapeCharacter()}},T.QueryParser=function(e,t){this.lexer=new T.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},T.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=T.QueryParser.parseClause;e;)e=e(this);return this.query},T.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},T.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},T.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},T.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case T.QueryLexer.PRESENCE:return T.QueryParser.parsePresence;case T.QueryLexer.FIELD:return T.QueryParser.parseField;case T.QueryLexer.TERM:return T.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(r+=" with value '"+t.str+"'"),new T.QueryParseError(r,t.start,t.end)}},T.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=T.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=T.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+t.str+"'";throw new T.QueryParseError(r,t.start,t.end)}var i=e.peekLexeme();if(null==i){r="expecting term or field, found nothing";throw new T.QueryParseError(r,t.start,t.end)}switch(i.type){case T.QueryLexer.FIELD:return T.QueryParser.parseField;case T.QueryLexer.TERM:return T.QueryParser.parseTerm;default:r="expecting term or field, found '"+i.type+"'";throw new T.QueryParseError(r,i.start,i.end)}}},T.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var r=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),i="unrecognised field '"+t.str+"', possible fields: "+r;throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.fields=[t.str];var n=e.peekLexeme();if(null==n){i="expecting term, found nothing";throw new T.QueryParseError(i,t.start,t.end)}if(n.type===T.QueryLexer.TERM)return T.QueryParser.parseTerm;i="expecting term, found '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}},T.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(null!=r)switch(r.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new T.QueryParseError(i,r.start,r.end)}else e.nextClause()}},T.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.editDistance=r;var n=e.peekLexeme();if(null!=n)switch(n.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:i="Unexpected lexeme type '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}else e.nextClause()}},T.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var i="boost must be numeric";throw new T.QueryParseError(i,t.start,t.end)}e.currentClause.boost=r;var n=e.peekLexeme();if(null!=n)switch(n.type){case T.QueryLexer.TERM:return e.nextClause(),T.QueryParser.parseTerm;case T.QueryLexer.FIELD:return e.nextClause(),T.QueryParser.parseField;case T.QueryLexer.EDIT_DISTANCE:return T.QueryParser.parseEditDistance;case T.QueryLexer.BOOST:return T.QueryParser.parseBoost;case T.QueryLexer.PRESENCE:return e.nextClause(),T.QueryParser.parsePresence;default:i="Unexpected lexeme type '"+n.type+"'";throw new T.QueryParseError(i,n.start,n.end)}else e.nextClause()}},b=this,P=function(){return T},"function"==typeof define&&define.amd?define(P):"object"==typeof exports?module.exports=P():b.lunr=P()}(); diff --git a/atomic-rollbacks/index.html b/atomic-rollbacks/index.html new file mode 100644 index 0000000000..bb56fd40bc --- /dev/null +++ b/atomic-rollbacks/index.html @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +Atomic Rollbacks | ostreedev/ostree + + + + + + + + + + + + + + + + + + + + + Skip to main content + + + Link + + + + + + + Menu + + + + + + + Expand + + + + + + + + (external link) + + + + + + Document + + + + + + + Search + + + + + + + + + + Copy + + + + + + + Copied + + + + + + + + + +