Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update custom installation docs #425

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 116 additions & 194 deletions docs/custom-install.md

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions docs/extra-rpms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
sidebar_label: Add third party RPMs
title: ''
---

<head>
<link rel="canonical" href="https://elemental.docs.rancher.com/custom-install/extra-rpms"/>
</head>

## How to add third party RPMs at install time

This example is covering the case in which extra RPMS (e.g. specific hardware drivers) are included
into the ISO and during the installation they are installed over the OS image.

For that use case the following files are required:

* additional RPMs to install
* additional cloud-config file defining hooks to copy and install binaries as installation hooks

We can handle it all into a single `SeedImage.spec.cloud-config` section assuming the additional
RPM is available to download it from a remote server at installation time.

Consider the following cloud-config data which could be used as the content of the `cloud-config`
section in a [SeedImage resource](seedimage-reference.md#seedimagespec-reference).

```yaml showLineNumbers
name: "Install extra drivers"
stages:
before-install:
# Preload data to the persistent storage
# During installation persistent partition is mounted at /run/elemental/persistent
- downloads:
- path: /tmp/some_package.rpm
url: "<REMOTE_PACKAGE_URL>"
permissions: 0777
- commands:
- mkdir -o /run/elemental/persistent/extra-pkgs
- cp -p /tmp/some_package.rpm /run/elemental/persistent/extra-pkgs

after-install-chroot:
# Install the package at install time
- commands:
- rpm -iv /run/elemental/extra-pkgs/some_package.rpm

# Include to the install system analog upgrade and reset hooks
- files:
- path: /oem/extra-pkg.yaml
permissions: 0664
content: |
name: "Install extra drivers"
stages:
after-upgrade-chroot:
# Install the package after upgrading to a new image
- commands:
- rpm -iv /run/elemental/extra-pkgs/some_package.rpm
after-reset-chroot:
# Install the package on reset
- commands:
- rpm -iv /run/elemental/extra-pkgs/some_package.rpm
```

Note the installation hooks only cover installation procedures, so that additional cloud-config data should
be also part of the installed system in order to keep installing the package as part of the upgrade or reset
processes.

### Repacking a generated ISO image with extra files

Alternatively, if having the dynamic download of content at install time is not a desired behavior
and an ISO already including all the extra binaries is the actual goal this can is also possible
but requires manually repacking the ISO.

Using `xorriso`, the linux utility to create ISOs, this turns to be a relatively easy process.

Let's create an `overlay` directory to create the directory tree that needs to be
added into the ISO root. In that case the `overlay` directory could contain:

```yaml showLineNumbers
overlay/
data/
extra-pkgs/
some_package.rpm
iso-config/
install_hooks.yaml
```

We are assuming the `install_hooks.yaml` is the content the actual cloud-config exposed in the previous
section which is manually included into image instead of being embedded in a SeedImage resource. The `data` folder is eventually including the binaries we want to append into the ISO.

Assuming we already downloaded an Elemental ISO tied to a specific MachineRegistration with the following
`xorriso` call all the `overlay` folder contents would be included into a new ISO:

```bash
xorriso -indev elemental.x86_64.iso -outdev elemental.custom.x86_64.iso -map overlay / -boot_image any replay
```

Requires `xorriso` equal or higher than version 1.5.

The contents of `install_hooks.yaml` could eventually be the same as the previous section but omiting the RPM
package download and also adapting the RPM path to `/run/initramfs/live/data/extra-pkgs/some_package.rpm` as
the ISO root folder is mounted at `/run/initramfs/live`.
102 changes: 102 additions & 0 deletions docs/lvm-drives-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
sidebar_label: Extra LVM volume group
title: ''
---

<head>
<link rel="canonical" href="https://elemental.docs.rancher.com/custom-install/lvm-drives-example"/>
</head>

## How to add extra LVM volume group disks during the installation

This example is covering the setup of a host with multiple disks and some of them used
as part of a LVM setup.

As an example, we have an host with three disks (`/dev/sda`, `/dev/sdb`
and `/dev/sdc`).

The first disk is used for a regular Elemental installation
and the other remaining two are used as part of a LVM group where arbitrary logical volumes
are created, formatted and mounted at boot time via an extended `fstab` file.

For this example cloud-config steps are required in two different stages. First, some
[installation hooks](cloud-config-reference.md#elemental-client-cloud-config-hooks) are
needed to prepare and handle LVM volumes during the installation. Second, a cloud-config
is required at boot time to ensure the created LVM volumes are included in `/etc/fstab`
and consequently mounted.

Installation hooks can be included to the `SeedImage.spec.cloud-config` section with something
like:

```yaml showLineNumbers
apiVersion: elemental.cattle.io/v1beta1
kind: SeedImage
metadata:
name: custom-seed
namespace: fleet-default
spec:
...
cloud-config:
name: "Create LVM logic volumes over some physical disks"
stages:
post-install:
- name: "Create physical volume, volume group and logical volumes"
if: '[ -e "/dev/sdb" ] && [ -e "/dev/sdc" ]'
commands:
- |
# Create the physical volume, volume group and logical volumes
pvcreate /dev/sdb /dev/sdc
vgcreate elementalLVM /dev/sdb /dev/sdc
lvcreate -L 8G -n elementalVol1 elementalLVM
lvcreate -l 100%FREE -n elementalVol2 elementalLVM
# Trigger udev detection
if [ ! -e "/dev/elementalLVM/elementalVol1" ] || [ ! -e "/dev/elementalLVM/elementalVol2" ]; then
sleep 10
udevadm settle
fi
# Ensure devices are already available
[ -e "/dev/elementalLVM/elementalVol1" ] || exit 1
[ -e "/dev/elementalLVM/elementalVol2" ] || exit 1
# Format logical volumes with a known label for later use in fstab
mkfs.xfs -L eVol1 /dev/elementalLVM/elementalVol1
mkfs.xfs -L eVol2 /dev/elementalLVM/elementalVol2
```

The LVM devices are created and formatted as desired. This is a good
example of an installation hook, as this setup is only needed once, at installation
time. As an alternative, the same action could be done on first boot, however it would
require a more sophisticated logic to ensure it's only applied once at first boot.

Finally, the boot time cloud-config data contains the mount point settings to trigger the
mounts. The Elemental OS `fstab` file is ephemeral and it's dynamically created at boot time.
That's why it doesn't exist during the installation and can't be used in an installation hook.

Consider the following example to customize the `/etc/fstab` file using the `cloud-config` section
of a MachineRegistration resource:

```yaml showLineNumbers
apiVersion: elemental.cattle.io/v1beta1
kind: MachineRegistration
metadata:
name: my-nodes
namespace: fleet-default
spec:
...
config:
...
cloud-config:
stages:
initramfs:
- name: "Extend fstab to mount LVM logical volumes at boot"
commands:
- |
echo "LABEL=eVol1 /run/elemental/eVol1 xfs defaults 0 0" >> /etc/fstab
echo "LABEL=eVol2 /run/elemental/eVol2 xfs defaults 0 0" >> /etc/fstab
```

:::note
The `initramfs` [stage](cloud-config-reference.md) is the last stage before switching to the actual
root tree. At this stage, the `/etc/fstab` file already exists and can be adapted before
switching root. Once running in the final root tree, SystemD will handle the rest of the
initialization and apply it.
:::
12 changes: 11 additions & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ const sidebars = {
"installation",
"upgrade",
"upgrade-lifecycle",
"custom-install",
"elemental-plans",
]
},
Expand Down Expand Up @@ -142,6 +141,17 @@ const sidebars = {
"label": "How to",
"items": [
"custom-images",
{
"type": "category",
"collapsible": true,
"collapsed": true,
"label": "Customize Elemental Installation",
"link": {"type": "doc", "id": "custom-install"},
"items": [
"extra-rpms",
"lvm-drives-example"
]
},
"elemental_behind_proxy",
"hostname",
"ntp",
Expand Down
Loading
Loading