Skip to content

Commit

Permalink
Merge branch 'image-manifest' of https://github.com/gerblesh/usway in…
Browse files Browse the repository at this point in the history
…to image-manifest
  • Loading branch information
gerblesh committed Sep 22, 2023
2 parents 9bd7bae + d40cd91 commit 54909da
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 44 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ jobs:
steps:
# Checkout push-to-registry action GitHub repository
- name: Checkout Push to Registry action
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Add yq (for reading recipe.yml)
uses: mikefarah/yq@v4.34.2
uses: mikefarah/yq@v4.35.1

- name: Gather image data from recipe
run: |
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
# Build metadata
- name: Image Metadata
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
id: meta
with:
images: |
Expand Down Expand Up @@ -165,7 +165,7 @@ jobs:
--disable-content-trust
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
uses: docker/login-action@v3
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/live'
with:
registry: ghcr.io
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-iso.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
image: fedora:38
options: --privileged
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Generate ISO
uses: ublue-os/isogenerator@main
id: isogenerator
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Don't worry, it only requires some basic knowledge about using the terminal and
After setup, it is recommended you update this README to describe your custom image.

> **Note**
> Everywhere in this repository, make sure to replace `ublue-os/startingpoint` with the details of your own repository. Unless you used [`create-ublue-image`](https://github.com/EinoHR/create-ublue-image), in which case the previous repo identifier should already be your repo's details.
> Everywhere in this repository, make sure to replace `ublue-os/startingpoint` with the details of your own repository. Unless you used one of the automatic repository setup tools in which case the previous repo identifier should already be your repo's details.
> **Warning**
> To start, you *must* create a branch called `live` which is exclusively for your customizations. That is the **only** branch the GitHub workflow will deploy to your container registry. Don't make any changes to the original "template" branch. It should remain untouched. By using this branch structure, you ensure a clear separation between your own "published image" branch, your development branches, and the original upstream "template" branch. Periodically sync and fast-forward the upstream "template" branch to the most recent revision. Then, simply rebase your `live` branch onto the updated template to effortlessly incorporate the latest improvements into your own repository, without the need for any messy, manual "merge commits".
Expand All @@ -29,7 +29,7 @@ After setup, it is recommended you update this README to describe your custom im

The easiest way to start customizing is by looking at and modifying `config/recipe.yml`. It's documented using comments and should be pretty easy to understand.

If you want to add custom configuration files, you can just add them in the `/usr/etc/` directory, which is the official OSTree "configuration template" directory and will be applied to `/etc/` on boot. `usr` is copied into your image by default. If you need to add other directories in the root of your image, that can be done in the Containerfile. Writing to `/var/` in the image builds of OSTree-based distros isn't supported and will not work, as that is a local user-managed directory!
If you want to add custom configuration files, you can just add them in the `/usr/etc/` directory, which is the official OSTree "configuration template" directory and will be applied to `/etc/` on boot. `config/files/usr` is copied into your image's `/usr` by default. If you need to add other directories in the root of your image, that can be done using the `files` module. Writing to `/var/` in the image builds of OSTree-based distros isn't supported and will not work, as that is a local user-managed directory!

For more information about customization, see [the README in the config directory](config/README.md)

Expand Down Expand Up @@ -95,4 +95,4 @@ Then type `just` to list the just recipes available.

The file `/usr/share/ublue-os/just/custom.just` is intended for the custom just commands (recipes) you wish to include in your image. By default, it includes the justfiles from [`ublue-os/bling`](https://github.com/ublue-os/bling), if you wish to disable that, you need to just remove the line that includes bling.just.

See [the just-page in the Universal Blue documentation](https://universal-blue.org/guide/just/) for more information.
See [the just-page in the Universal Blue documentation](https://universal-blue.org/guide/just/) for more information.
55 changes: 32 additions & 23 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,41 @@ MODULE_DIRECTORY="/tmp/modules"

# https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#yq-in-a-bash-loop
get_yaml_array() {
# creates array $1 with content at key $2 from $3
# creates array $1 with content at key $2 from $3
readarray "$1" < <(echo "$3" | yq -I=0 "$2")
}
export -f get_yaml_array # this makes the function available to all modules

run_module() {
MODULE="$1"
TYPE=$(echo "$MODULE" | yq '.type')
if [[ "$TYPE" != "null" ]]; then
# If type is found, that means that the module config
# has been declared inline, and thus is safe to pass to the module
echo "=== Launching module of type: $TYPE ==="
bash "$MODULE_DIRECTORY/$TYPE/$TYPE.sh" "$MODULE"
else
# If the type is not found, that means that the module config
# is in a separate file, and has to be read from it
FILE=$(echo "$MODULE" | yq '.from-file')
run_modules "$CONFIG_DIRECTORY/$FILE"
fi
echo "======"
}

run_modules() {
MODULES_FILE="$1"
readarray MODULES < <(yq -o=j -I=0 '.modules[]' "$MODULES_FILE" )
if [[ ${#MODULES[@]} -gt 0 ]]; then
for MODULE in "${MODULES[@]}"; do
run_module "$MODULE"
done
else
MODULE=$(yq -o=j -I=0 '.' "$MODULES_FILE")
run_module "$MODULE"
fi
}

# Declare dynamically generated variables as exported
declare -x IMAGE_NAME BASE_IMAGE OS_VERSION

Expand All @@ -32,25 +62,4 @@ OS_VERSION="$(grep -Po '(?<=VERSION_ID=)\d+' /usr/lib/os-release)"
# Welcome.
echo "Building $IMAGE_NAME from $BASE_IMAGE:$OS_VERSION."

# Run each module
readarray MODULES < <(yq -o=j -I=0 '.modules[]' "$RECIPE_FILE" )

for MODULE in "${MODULES[@]}"; do
TYPE=$(echo "$MODULE" | yq '.type')
if [[ "$TYPE" != "null" ]]; then
# If type is found, that means that the module config
# has been declared inline, and thus is safe to pass to the module
echo "=== Launching module of type: $TYPE ==="
bash "$MODULE_DIRECTORY/$TYPE/$TYPE.sh" "$MODULE"
else
# If the type is not found, that means that the module config
# is in a separate file, and has to be read from it
FILE=$(echo "$MODULE" | yq '.from-file')
MODULE_CONFIG=$(yq -o=j -I=0 '.' "$CONFIG_DIRECTORY/$FILE")

TYPE=$(echo "$MODULE_CONFIG" | yq '.type')
echo "=== Launching module of type: $TYPE ==="
bash "$MODULE_DIRECTORY/$TYPE/$TYPE.sh" "$MODULE_CONFIG"
fi
echo "======"
done
run_modules "$RECIPE_FILE"
27 changes: 19 additions & 8 deletions config/README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
# Configuring your image

The main file of your is *the recipe file*. You can have multiple recipe files, and the ones to build are declared in the matrix section of [build.yml](../.github/workflows/build.yml).
The main file of your is *the recipe file*. You can have multiple recipe files, and the ones to build are declared in the matrix section of [build.yml](../.github/workflows/build.yml).

## Basic options

At the top of the recipe, there are four *mandatory* configuration options.

`name:` is the name of the image that is used when rebasing to it. For example, the name "sapphire" would result in the final URL of the container being `ghcr.io/<yourusername>/sapphire`.

`description:` is a short description of your image that will be attached to your image's metadata.
`description:` is a short description of your image that will be attached to your image's metadata.

`base-image:` is the URL of the image your image will be built upon.
`base-image:` is the URL of the image your image will be built upon.

`image-version:` is the version tag of the `base-image` that will be pulled. For example, Universal Blue's images build with Fedora version tags (`38`, `39`), with the `latest` tag for the latest major version, and [many other tags](https://github.com/ublue-os/main/pkgs/container/base-main/versions?filters%5Bversion_type%5D=tagged).

## Modules

The core of startingpoint's configuration is built around the idea of modules. Modules are scripts in the [`../modules`](../modules/) directory that you list out under `modules:` in the recipe. They are executed in order, and can run arbitrary shell commands and write any files.
The core of startingpoint's configuration is built around the idea of modules. Modules are scripts in the [`../modules`](../modules/) directory that you configure under `modules:` in the recipe. They are executed in order, and can run arbitrary shell commands and write any files.

This repository fetches some useful default modules from [`ublue-os/bling`](https://github.com/ublue-os/bling/), like [`rpm-ostree`](../modules/rpm-ostree) for pseudo-declarative package management, [`bling`](../modules/bling) for pulling extra components from [`ublue-os/bling`](https://github.com/ublue-os/bling), and [`files`](../modules/files) for copying files from the `config/files/` directory into your image. For a comprehensive list of modules and their in-depth documentation, check out [the modules page on the website](https://universal-blue.org/tinker/modules/).
This repository fetches some useful default modules from [`ublue-os/bling`](https://github.com/ublue-os/bling/), like [`rpm-ostree`](https://universal-blue.org/tinker/modules/rpm-ostree) for pseudo-declarative package management, [`bling`](https://universal-blue.org/tinker/modules/bling) for pulling extra components from [`ublue-os/bling`](https://github.com/ublue-os/bling), and [`files`](https://universal-blue.org/tinker/modules/files) for copying files from the `config/files/` directory into your image.

### Including modules from other files and building multiple images
For a comprehensive list of modules, their in-depth documentation and example configuration, check out [the Modules page on the website](https://universal-blue.org/tinker/modules/).

### Building multiple images and including module configuration from other files and

To build multiple images, you need to create another recipe.yml file, which you should name based on what kind of image you want it to build. Then, edit the [`build.yml`](../.github/workflows/build.yml) file. Inside the file, under `jobs: strategy: matrix:`, there's a list of recipe files to build images, which you need to add your new recipe file to. These should be paths to files inside the `config` directory.

Module configuration can be included from other files using the `from-file` syntax. The valye should be a path to a file inside the `config` directory. For example, the following snippet could be used to include the configuration for installing a set of packages common to multiple images.
```yml
Module configuration can be included from other files using the `from-file` syntax. The value should be a path to a file inside the `config` directory. For example, the following snippet could be used to include the configuration for installing a set of packages common to multiple images.
```yaml
modules:
- from-file: common-packages.yml
```
And inside config/common-packages.yml
```yaml
type: rpm-ostree
install:
- i3
- dunst
- rofi
- kitty
```
12 changes: 7 additions & 5 deletions config/recipe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ description: A starting point for further customization of uBlue images. Make yo
base-image: ghcr.io/ublue-os/silverblue-main
image-version: 38 # latest is also supported if you want new updates ASAP

# list of modules, executed in order
# module configuration, executed in order
# you can include multiple instances of the same module
modules:

- type: files
files:
- usr: /usr # copy static configurations
# configuration you wish to end up in /etc/ on the booted system should be
# added into /usr/etc/ as that is the proper "distro" config directory on ostree
# read more in the files module's README
#
# copies config/files/usr into your image's /usr
#
# configuration you wish to end up in /etc/ on the booted system
# should be added into /usr/etc/ as that is the proper "distro"
# config directory on ostree. Read more in the files module's README

- type: rpm-ostree
repos:
Expand Down

0 comments on commit 54909da

Please sign in to comment.