-
Notifications
You must be signed in to change notification settings - Fork 27
Added toolkit docs #207
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
Draft
nunix
wants to merge
5
commits into
rancher:main
Choose a base branch
from
nunix:toolkit-migration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Added toolkit docs #207
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
e134afb
Added toolkit docs
nunix 7100c0d
Updated all toolkit links
nunix 8bda26e
Merge remote-tracking branch 'upstream/main' into toolkit-migration
nunix a4be415
Merge remote-tracking branch 'upstream/main' into toolkit-migration
nunix 8e12d24
Merge remote-tracking branch 'upstream/main' into toolkit-migration
nunix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
|
|
||
| --- | ||
| title: "Creating derivatives" | ||
| sidebar_label: "Creating derivatives" | ||
| weight: 4 | ||
| date: 2023-05-11 | ||
| description: > | ||
| Documents various methods for creating Elemental derivatives | ||
| --- | ||
|
|
||
| A derivative is a standard container image which can be booted by Elemental. | ||
|
|
||
| We can identify a build phase where we build the derivative, and a "runtime phase" where we consume it. | ||
|
|
||
| The image is described by a Dockerfile, composed of a base OS of choice (e.g. openSUSE, Ubuntu, etc. ) and the Elemental toolkit itself in order to be consumed by Elemental and allow to be upgraded from by other derivatives. | ||
|
|
||
| elemental-toolkit then converts the OCI artifact into a bootable medium (ISO, packer, ova, etc) and the image itself then can be used to bootstrap other derivatives, which can in turn upgrade to any derivative built with Elemental. | ||
|
|
||
| A derivative can also be later re-used again as input as base-image for downstream derivatives. | ||
|
|
||
| All the documentation below imply that the container image generated will be the booting one, there are however several configuration entrypoint that you should keep in mind while building the image which are general across all the implementation: | ||
|
|
||
| - Custom persistent runtime configuration has to be provided in `/system/oem` for derivatives, [see also the documentation section](../customizing/configuration_persistency). Everything under `/system/oem` will be loaded during the various stages (boot, network, initramfs). | ||
| - `/etc/cos/bootargs.cfg` contains the booting options required to boot the image with GRUB, [see grub customization](../customizing/configure_grub) | ||
|
|
||
| Derivatives inherits `Elemental` defaults, which you can override during the build process, however there are some defaults which are relevant and listed below: | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| --- | ||
| title: "Build disk images with Elemental" | ||
| sidebar_label: "Build disk images with Elemental" | ||
| --- | ||
|
|
||
| Requirements: | ||
|
|
||
| * `qemu-img` utility | ||
| * `elemental` binary | ||
| * elemental runtime dependencies | ||
|
|
||
| The suggested approach is based on using the Elemental installer (`elemental install` command) to run the installation | ||
| from a Linux to a loop device. The loop device can be a raw image created with `qemu-img create` that can easily be | ||
| converted to other formats after the installation by using `qemu-img convert`. | ||
|
|
||
| ## Prepare the loop device | ||
|
|
||
| Preparing the a loop device for the installation is simple and straight forward. | ||
|
|
||
| ```bash | ||
| # Create a raw image of 32G | ||
| > qemu-img create -f raw disk.img 32G | ||
|
|
||
| # Set the disk image as a loop device | ||
| > sudo losetup -f --show disk.img | ||
| <device> | ||
| ``` | ||
|
|
||
| ## Run elemental installation | ||
|
|
||
| Execute the elemental installation as described in [installing](../getting-started/install): | ||
|
|
||
| ```bash | ||
| > sudo elemental install --firmware efi --system.uri oci:<image=ref> <device> | ||
| ``` | ||
|
|
||
| Where `<image-ref>` is the Elemental derivative container image we want to use for the disk creation and `<device>` is the | ||
| loop device previously created with `losetup` (e.g. `/dev/loop0`). | ||
|
|
||
|
|
||
| ## Convert the RAW image to desired format | ||
|
|
||
| Once the installation is done just unsetting the loop device and converting the image to the desired format is missing: | ||
|
|
||
| ```bash | ||
| # Unset the loop device | ||
| > sudo losetup -d <device> | ||
|
|
||
| # Convert the RAW image to qcow2 | ||
| > qemu-img convert -f raw -O qcow2 disk.img disk.qcow2 | ||
| ``` | ||
|
|
||
| QEMU supports a wide range of formats including common ones such as `vdi`, `vmdk` or `vhdx`. | ||
|
|
||
| The result can be easily tested on QEMU with: | ||
|
|
||
| ```bash | ||
| > qemu -m 4096 -hda disk.qcow2 -bios /usr/share/qemu/ovmf-x86_64.bin | ||
| ``` | ||
|
|
||
| Note the firmware image path varies depending on the host distro, the path provided in this example is based on openSUSE Leap. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| --- | ||
| title: "Build ISOs" | ||
| sidebar_label: "Build ISOs" | ||
| --- | ||
|
|
||
| In order to build an ISO we rely on `elemental build-iso` command. It accepts a YAML file denoting the sources to bundle in an ISO. In addition it can also overlay custom files or use container images from a registry as packages. | ||
|
|
||
| To build an ISO, just run: | ||
|
|
||
| ```bash | ||
| docker run --rm -ti -v $(pwd):/build ghcr.io/rancher/elemental-toolkit/elemental-cli:latest --debug build-iso -o /build $SOURCE | ||
| ``` | ||
|
|
||
| Where `$SOURCE` might be the container image you want to build the ISO for, you might want to check on [how to build bootable images](creating_bootable_images). Argument `$SOURCE` might be the reference to the directory, file, container image or channel we are building the ISO for, it should be provided as uri in following format `<sourceType>:<sourceName>`, where: | ||
| * `<sourceType>` - might be ["dir", "file", "oci", "docker"], as default is taken "docker" | ||
| * `<sourceName>` - is path to file or directory, channel or image name with tag version (if tag was not provided then "latest" is used) | ||
|
|
||
| `elemental build-iso` command also supports reading a configuration `manifest.yaml` file. It is loaded form the directory specified by `--config-dir` elemental's flag. | ||
|
|
||
| An example of a yaml file using the bootloader from the contained image: | ||
|
|
||
| ```yaml | ||
| iso: | ||
| bootloader-in-rootfs: true | ||
| grub-entry-name: "Installer" | ||
|
|
||
| name: "Elemental-0" | ||
| date: true | ||
| ``` | ||
|
|
||
| ## What's next? | ||
|
|
||
| - Check out on how to [build an image](build_disk) from the ISO we have just created | ||
|
|
||
| ## Syntax | ||
|
|
||
| Below you can find a full reference about the yaml file format. | ||
|
|
||
| ```yaml | ||
| iso: | ||
| # Sources to be installed in the rootfs | ||
| rootfs: | ||
| - .. | ||
| # Sources to be installed in the uefi image | ||
| uefi: | ||
| - .. | ||
| # Sources to be installed in the iso image | ||
| image: | ||
| - .. | ||
| label: "COS_LIVE" | ||
| ``` | ||
|
|
||
| Sources can be an image reference (then an explicit tag is required) or a local path. Sources are stacked in the given order, so one can easily overwrite or append data by simply adding a local path as the last source. | ||
|
|
||
| ### Command flags | ||
|
|
||
| - **name**: Name of the ISO image. It will be used to generate the `*.iso` file name | ||
| - **output**: Path of the destination folder of created images | ||
| - **date**: If present it includes the date in the generated file name | ||
| - **overlay-rootfs**: Sets the path of a tree to overlay on top of the system root-tree | ||
| - **overlay-uefi**: Sets the path of a tree to overaly on top of the EFI image root-tree | ||
| - **overlay-iso**: Sets the path of a tree to overlay on top of the ISO filesystem root-tree | ||
| - **label**: Sets the volume label of the ISO filesystem | ||
|
|
||
| ## Configuration reference | ||
|
|
||
| ### `iso.rootfs` | ||
|
|
||
| A list of sources in uri format (container image or local path) [ "docker", "oci", "dir", "file" ] to install in the rootfs. The rootfs will be squashed to a `rootfs.squashfs` file | ||
|
|
||
| ### `iso.uefi` | ||
|
|
||
| A list of sources in uri format (container image or local path) [ "docker", "oci", "dir", "file" ] to install in the efi FAT image or partition. | ||
|
|
||
| ### `iso.image` | ||
|
|
||
| A list of sources in uri format (container image or local path) [ "docker", "oci", "dir", "file" ] to install in ISO filesystem. | ||
|
|
||
| ### `iso.label` | ||
|
|
||
| The label of the ISO filesystem. Defaults to `COS_LIVE`. Note this value is tied with the bootloader and kernel parameters to identify the root device. | ||
|
|
||
| ### `name` | ||
|
|
||
| A string representing the ISO final image name without including the `.iso` | ||
|
|
||
| ### `date` | ||
|
|
||
| Boolean indicating if the output image name has to contain the date | ||
|
|
||
| ### `output` | ||
|
|
||
| Folder destination of the built artifacts. It attempts to create if it doesn't exist. | ||
|
|
||
| ## Customize bootloader with GRUB | ||
|
|
||
| Boot menu and other bootloader parameters can then be easily customized by using the overlay parameters within the ISO config yaml manifest. | ||
|
|
||
| Assuming the ISO being built includes: | ||
|
|
||
| ```yaml | ||
| iso: | ||
| rootfs: | ||
| - ... | ||
| uefi: | ||
| - oci:example-grub2-efi-image:latest | ||
| image: | ||
| - oci:example-grub2:latest | ||
| - oci:example-grub2-efi-image:latest | ||
| ``` | ||
|
|
||
| We can customize either the `image` packages (in the referrence image `live/grub2` package | ||
| includes bootloader configuration) or make use of the overlay concept to include or | ||
| overwrite addition files for `image` section. | ||
|
|
||
| Consider the following example: | ||
|
|
||
| ```yaml | ||
| iso: | ||
| rootfs: | ||
| - ... | ||
| uefi: | ||
| - oci:example-grub2-efi-image:latest | ||
| image: | ||
| - oci:example-grub2:latest | ||
| - oci:example-grub2-efi-image:latest | ||
| - dir:/my/path/to/overlay/iso | ||
| ``` | ||
|
|
||
| With the above the ISO will also include the files under `/my/path/to/overlay/iso` path. To customize the boot | ||
| menu parameters consider copy and modify relevant files from `example-grub2:latest` image. In this example the | ||
| `overlay` folder files list could be: | ||
|
|
||
| ```bash | ||
| # image files for grub2 boot | ||
| boot/grub2/grub.cfg | ||
| ``` | ||
|
|
||
| Being `boot/grub2/grub.cfg` a custom grub2 configuration including custom boot menu entries. Consider the following `grub.cfg` example: | ||
|
|
||
| ``` | ||
| search --file --set=root /boot/kernel.xz | ||
| set default=0 | ||
| set timeout=10 | ||
| set timeout_style=menu | ||
| set linux=linux | ||
| set initrd=initrd | ||
| if [ "${grub_cpu}" = "x86_64" -o "${grub_cpu}" = "i386" ];then | ||
| if [ "${grub_platform}" = "efi" ]; then | ||
| set linux=linuxefi | ||
| set initrd=initrdefi | ||
| fi | ||
| fi | ||
|
|
||
| set font=($root)/boot/x86_64/loader/grub2/fonts/unicode.pf2 | ||
| if [ -f ${font} ];then | ||
| loadfont ${font} | ||
| fi | ||
|
|
||
| menuentry "Custom grub2 menu entry" --class os --unrestricted { | ||
| echo Loading kernel... | ||
| $linux ($root)/boot/kernel.xz cdroot root=live:CDLABEL=COS_LIVE rd.live.dir=/ rd.live.squashimg=rootfs.squashfs console=tty1 console=ttyS0 rd.cos.disable | ||
| echo Loading initrd... | ||
| $initrd ($root)/boot/rootfs.xz | ||
| } | ||
| ``` | ||
|
|
||
| ## Separate recovery | ||
|
|
||
| To make an ISO with a separate recovery image as squashfs, you can either use the default from `Elemental`, by adding it in the iso yaml file: | ||
|
|
||
| ```yaml | ||
| iso: | ||
| rootfs: | ||
| .. | ||
| uefi: | ||
| .. | ||
| image: | ||
| ... | ||
| - oci:example-recovery:latest | ||
| ``` | ||
|
|
||
| The installer will detect the squashfs file in the iso, and will use it when installing the system. You can customize the recovery image as well by providing your own. | ||
|
|
||
56 changes: 56 additions & 0 deletions
56
docs/toolkit/creating-derivatives/creating_bootable_images.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| --- | ||
| title: "Creating bootable images" | ||
| sidebar_label: "Creating bootable images" | ||
| --- | ||
|
|
||
|  | ||
|
|
||
| A derivative is a simple container image which can be processed by the Elemental toolkit in order to be bootable and installable. This section describes the requirements to create a container image that can be run by `Elemental`. | ||
|
|
||
| ## Requirements | ||
| {{<image_right image="https://docs.google.com/drawings/d/e/2PACX-1vQBfT10W88mD1bbReDmAJIOPF3tWdVHP7QE9w7W7ByOIzoKGOdh2z5YWsKf7wn8csFF_QGrDXgGsPWg/pub?w=478&h=178">}} | ||
|
|
||
| Bootable images are standard container images, that means the usual `build` and `push` workflow applies, and building images is also a way to persist [oem customizations](../customizing/oem_configuration). | ||
|
|
||
| The base image can be any Linux distribution that is compatible with our flavors. | ||
|
|
||
| The image needs to ship: | ||
| - parts of the elemental-toolkit (required, see below) | ||
| - kernel (required) | ||
| - initrd (required) | ||
| - grub2 (required) | ||
| - dracut (required) | ||
| - microcode (optional, not required in order to boot, but recomended) | ||
|
|
||
| ## Example | ||
|
|
||
| An illustrative example can be: | ||
|
|
||
|
|
||
| <!--{{<githubembed repo="rancher/elemental-toolkit" file="examples/green/Dockerfile" lang="Dockerfile">}}--> | ||
|
|
||
| In the example above, the elemental-toolkit parts that are **required** are pulled in by `COPY --from=TOOLKIT /install-root /`. | ||
|
|
||
| ## Initrd | ||
| The image should provide at least `grub`, `systemd`, `dracut`, a kernel and an initrd. Those are the common set of packages between derivatives. See also [package stack](package_stack). | ||
| By default the initrd is expected to be symlinked to `/boot/initrd` and the kernel to `/boot/vmlinuz`, otherwise you can specify a custom path while [building an iso](build_iso) and [by customizing grub](../customizing/configure_grub). | ||
|
|
||
| ## Building | ||
|
|
||
|  | ||
|
|
||
| The workflow would be then: | ||
|
|
||
| 1) `docker build` the image | ||
| 2) `docker push` the image to some registry | ||
| 3) `elemental upgrade --docker-image $IMAGE` from a Elemental machine or (`elemental reset` if bootstrapping a cloud image) | ||
|
|
||
| The following can be incorporated in any standard gitops workflow. | ||
|
|
||
| You can explore more examples in the [example section](../examples/creating_bootable_images) on how to create bootable images. | ||
|
|
||
| ## What's next? | ||
|
|
||
| Now that we have created our derivative container, we can either: | ||
|
|
||
| - [Build an iso](build_iso) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| title: "Package stack" | ||
| sidebar_label: "Package stack" | ||
| --- | ||
|
|
||
|
|
||
| When building a `elemental-toolkit` derivative, a common set of packages are required with a common default configuration. Some of the most notably are: | ||
|
|
||
| - systemd as init system | ||
| - grub for boot loader | ||
| - dracut for initramfs |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
|
|
||
| --- | ||
| title: "Customizing" | ||
| sidebar_label: "Customizing" | ||
| weight: 3 | ||
| date: 2017-01-05 | ||
| description: > | ||
| This section contains various articles relative on how to customize Elemental, branding and behavior. | ||
| --- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| --- | ||
| title: "Configuration persistency" | ||
| sidebar_label: "Configuration persistency" | ||
| --- | ||
|
|
||
|
|
||
| By default Elemental and derivatives are reading and executing cloud-init files in (lexicopgrahic) sequence inside: | ||
|
|
||
| - `/system/oem` | ||
| - `/usr/local/cloud-config` | ||
| - `/oem` | ||
|
|
||
| It is also possible to run cloud-init file in a different location (URLs included, too) from boot cmdline by using the `cos.setup=..` option. | ||
|
|
||
| {{% alert title="Note" %}} | ||
| It is possible to install a custom [cloud-init style file](../reference/cloud_init/) during install with `--cloud-init` flag on `elemental install` command or, it's possible to add one or more files manually inside the `/oem` directory after installation. | ||
| {{% /alert %}} | ||
|
|
||
| While `/system/oem` is reserved for system configurations to be included directly in the derivative container image, the `/oem` folder instead is reserved for persistent cloud-init files that can be extended in runtime. | ||
|
|
||
| For example, if you want to change `/etc/issue` of the system persistently, you can create `/usr/local/cloud-config/90_after_install.yaml` or alternatively in `/oem/90_after_install.yaml` with the following content: | ||
|
|
||
| ```yaml | ||
| # The following is executed before fs is setted up: | ||
| stages: | ||
| fs: | ||
| - name: "After install" | ||
| files: | ||
| - path: /etc/issue | ||
| content: | | ||
| Welcome, have fun! | ||
| permissions: 0644 | ||
| owner: 0 | ||
| group: 0 | ||
| - name: "After install (second step)" | ||
| files: | ||
| - path: /etc/motd | ||
| content: | | ||
| Welcome, have more fun! | ||
| permissions: 0644 | ||
| owner: 0 | ||
| group: 0 | ||
| ``` | ||
|
|
||
| For more examples you can find `/system/oem` inside Elemental vanilla images containing files used to configure on boot a pristine `Elemental`. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Porting of rancher/elemental-toolkit#2026