Deploy and configure an OSTree commit
pip install deploy-ostree==1.3.0
deploy-ostree
is a tool to deploy and configure an OSTree commit
without user input from a simple configuration file. It will:
Its original intended use case was automatic tests; accordingly, it should not
be seen as a replacement for an end-user installer. deploy-ostree
can serve
as a tool to install a regular system, but it may also take shortcuts and do
things in a way that are fine for a disposable test environment, but might not
be fine in long-lived system.
Running deploy-ostree
from inside a libostree deployment requires no
additional configuration (provided the bootloader is set up correctly). To run
deploy-ostree
on a system that's not using libostree, you need to first run
ostree admin init-fs /
to set up the libostree system repository and directory
structure. In addition, you may need to set up the bootloader. How to do this
depends on the OS, the architecture, and the bootloader in use.
You can install deploy-ostree using pip:
$ pip3 install deploy-ostree
# deploy-ostree <config path or HTTP URL>
This requires root permissions. If deploy-ostree
exits successfully, your new
OSTree deployment should be ready to boot.
/
. Just like for /
, the directory needs to exist and be
initialized for libostree use with ostree admin init-fs <sysroot path>
.root
boot parameter to the given value.
By default, the root
parameter of the current boot is used./etc/fstab
. If
this parameter is omitted, the system fstab (/etc/fstab
) is used.While not recommended, certain combinations of SELinux-using host systems and SELinux-using deployed systems might require disabling SELinux before deploying to avoid clashes between the host's SELinux policies and the SELinux labels in the deployed tree. To temporarily disable SELinux:
# setenforce 0
Configuration files must be either valid JSON or TOML files. The
syntax of a configuration is determined by its file extension: if it's .toml
(case-insensitive), it's parsed as a TOML file. Otherwise, it's considered a
JSON file. While the syntax of the formats obviously differs, the structure
used by deploy-ostree
is the same for both, which means JSON configuration
files can be converted to TOML using a generic JSON-to-TOML converter (and
vice versa).
Both formats use the same top-level configuration keys:
Script provisioners allow you to run custom script snippets defined inline in your configuration file. These will be run in the deployment directory after deployment, with both /etc and /var available.
The script is specified with the script
key. The script text will be fed to
the interpreter over stdin. The interpreter is /bin/sh
by default, but can be
overridden using the interpreter
key. Note that the interpreter needs to be
able to consume a script from stdin with no further arguments. An optional
description can be set with the description
key. This line will be shown
during deploying to describe the provisioning step.
The working directory of the script is set to the root directory of the deployment. Accordingly, any paths in the deployment should be relative to the current directory. Note that the script is not chrooted in any way. This means you can mess up the host system from your script if you're not careful!
If you need to run binaries from the deployed system, you can manually chroot into the deployment directory. Ultimately, you have to weigh depending on your usecase whether you want to rely on the host system for any tools you need, or whether you want to run things from the deployed system. Keep in mind that when deploying cross-architecture, running binaries from the deployed system may not work.
JSON example:
{
"script": "echo my-system > ./etc/hostname",
"interpreter": "/bin/bash",
"description": "hostname"
}
TOML example:
[[provisioners]]
script = "echo my-system > ./etc/hostname"
interpreter = "/bin/bash"
description = "hostname"
These are the provisioners included with deploy-ostree
. The name of the
provisioner must be set with the key builtin
on the configuration object. Any
options documented below must also be specified in the provisioner configuration
object.
JSON example:
{
"builtin": "root-password",
"password": "password"
}
TOML example:
[[provisioners]]
builtin = "root-password"
password = "password"
Set up the loopback interface and one other interface for DHCP with /etc/network/interfaces. This probably only applies to Debian-based systems and only for DHCP configuration. If you need different configuration, you will have to supply your own provisioner or use something like NetworkManager.
/proc/net/route
. However, this might
differ between systems (especially if only one is using
predictable interface names) so it's not guaranteed to work.Set the root password.
Create a user. This does try to create the home directory, but if your system
requires anything more than the stateroot's /var
being mounted, it may not
work.
Set up a user for passwordless sudo
access. For this to have any effect,
sudo
must be installed on your system.
Copy an SSH authorized_keys
file from the host system into the deployed
system. This is useful in Vagrant scenarios, as it allows you to copy
the SSH key used by Vagrant into the deployed system.
deploy-ostree
, not in the
deployed system..ssh/authorized_keys
inside the user's home directory.Create an /etc/machine-id
file containing a random UUID. If the file already
exists, it's not overwritten. This is necessary to get D-Bus to work on systems
that don't create a machine ID file on boot if missing.
/etc/machine-id
is used.
Any directories in the path that are missing will be created.This configuration will download and deploy CentOS Atomic Host,
set up /etc/fstab
, and create a user and set it up for passwordless sudo
.
JSON:
{
"url": "http://mirror.centos.org/centos/7/atomic/x86_64/repo/",
"ref": "centos-atomic-host/7/x86_64/standard",
"remote": "centos-atomic",
"stateroot": "centos-atomic-host",
"kernel-args": ["quiet", "splash"],
"provisioners": [
{
"builtin": "create-user",
"username": "atomic",
"password": "atomic",
"shell": "/usr/bin/bash"
},
{
"script": "echo centos-atomic-host > etc/hostname",
"description": "hostname"
},
{
"builtin": "passwordless-sudo",
"user": "atomic"
}
]
}
TOML:
url = "http://mirror.centos.org/centos/7/atomic/x86_64/repo/"
ref = "centos-atomic-host/7/x86_64/standard"
remote = "centos-atomic"
stateroot = "centos-atomic-host"
kernel-args = ["quiet", "splash"]
[[provisioners]]
builtin = "create-user"
username = "atomic"
password = "atomic"
shell = "/usr/bin/bash"
[[provisioners]]
script = "echo centos-atomic-host > etc/hostname"
description = "hostname"
[[provisioners]]
builtin = "passwordless-sudo"
user = "atomic"
Note that CentOS Atomic Host includes cloud-init which means it will spend some time unsuccessfully doing its cloud setup. This is awkward, but there's not a lot of OSTree systems to demonstrate with so here we are.
See the changelog for a list of versions and their changes.