diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f7c1b2a1c..e20fb15bc5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ # This workflow builds every branch of the repository daily at 20:22 UTC, one hour after ublue-os/nvidia builds. # The images are also built after pushuing changes or pull requests. -# The builds can also be triggered manually in the Actions tab thanks to workflow dispatch. +# The builds can also be triggered manually in the Actions tab thanks to workflow dispatch. # Only the branch called `live` is published. diff --git a/Containerfile b/Containerfile index a622d04079..5ea9284bf3 100644 --- a/Containerfile +++ b/Containerfile @@ -21,18 +21,9 @@ ARG RECIPE=recipe.yml # The default image registry to write to policy.json and cosign.yaml ARG IMAGE_REGISTRY=ghcr.io/ublue-os -# Copy static configurations and component files. -# Warning: If you want to place anything in "/etc" of the final image, you MUST -# place them in "./usr/etc" in your repo, so that they're written to "/usr/etc" -# on the final system. That is the proper directory for "system" configuration -# templates on immutable Fedora distros, whereas the normal "/etc" is ONLY meant -# for manual overrides and editing by the machine's admin AFTER installation! -# See issue #28 (https://github.com/ublue-os/startingpoint/issues/28). -COPY usr /usr - COPY cosign.pub /usr/share/ublue-os/cosign.pub -COPY config /usr/share/ublue-os/startingpoint +COPY config /tmp/config # Copy the bling from ublue-os/bling into tmp, to be installed later by the bling module # Feel free to remove these lines if you want to speed up image builds and don't want any bling diff --git a/build.sh b/build.sh index 5640c57bbd..7d33c221a0 100644 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ # Tell build process to exit if there are any errors. set -oue pipefail -export CONFIG_DIRECTORY="/usr/share/ublue-os/startingpoint" +export CONFIG_DIRECTORY="/tmp/config" RECIPE_FILE="$CONFIG_DIRECTORY/$RECIPE" MODULE_DIRECTORY="/tmp/modules" @@ -53,4 +53,4 @@ for MODULE in "${MODULES[@]}"; do bash "$MODULE_DIRECTORY/$TYPE/$TYPE.sh" "$MODULE_CONFIG" fi echo "======" -done \ No newline at end of file +done diff --git a/usr/share/ublue-os/firstboot/launcher/autostart.desktop b/config/files/usr/share/ublue-os/firstboot/launcher/autostart.desktop similarity index 100% rename from usr/share/ublue-os/firstboot/launcher/autostart.desktop rename to config/files/usr/share/ublue-os/firstboot/launcher/autostart.desktop diff --git a/usr/share/ublue-os/firstboot/launcher/autostart.sh b/config/files/usr/share/ublue-os/firstboot/launcher/autostart.sh similarity index 100% rename from usr/share/ublue-os/firstboot/launcher/autostart.sh rename to config/files/usr/share/ublue-os/firstboot/launcher/autostart.sh diff --git a/usr/share/ublue-os/firstboot/launcher/launcher-flowchart.png b/config/files/usr/share/ublue-os/firstboot/launcher/launcher-flowchart.png similarity index 100% rename from usr/share/ublue-os/firstboot/launcher/launcher-flowchart.png rename to config/files/usr/share/ublue-os/firstboot/launcher/launcher-flowchart.png diff --git a/usr/share/ublue-os/firstboot/launcher/login-profile.sh b/config/files/usr/share/ublue-os/firstboot/launcher/login-profile.sh similarity index 100% rename from usr/share/ublue-os/firstboot/launcher/login-profile.sh rename to config/files/usr/share/ublue-os/firstboot/launcher/login-profile.sh diff --git a/usr/share/ublue-os/firstboot/yafti.yml b/config/files/usr/share/ublue-os/firstboot/yafti.yml similarity index 100% rename from usr/share/ublue-os/firstboot/yafti.yml rename to config/files/usr/share/ublue-os/firstboot/yafti.yml diff --git a/usr/share/ublue-os/just/custom.just b/config/files/usr/share/ublue-os/just/custom.just similarity index 100% rename from usr/share/ublue-os/just/custom.just rename to config/files/usr/share/ublue-os/just/custom.just diff --git a/config/recipe.yml b/config/recipe.yml index 0ca857ab1c..8e70381a84 100644 --- a/config/recipe.yml +++ b/config/recipe.yml @@ -8,10 +8,23 @@ base-image: ghcr.io/ublue-os/silverblue-main image-version: 38 # latest is also supported if you want new updates ASAP # list of modules that will be executed in order + # you can include multiple of the same module + modules: + - type: files + files: + - usr: /usr + # Copy static configurations and component files. + # Warning: If you want to place anything in "/etc" of the final image, you MUST + # place them in "./usr/etc" in your repo, so that they're written to "/usr/etc" + # on the final system. That is the proper directory for "system" configuration + # templates on immutable Fedora distros, whereas the normal "/etc" is ONLY meant + # for manual overrides and editing by the machine's admin AFTER installation! + # See issue #28 (https://github.com/ublue-os/startingpoint/issues/28). + - type: rpm-ostree - repos: + repos: # - https://copr.fedorainfracloud.org/coprs/atim/starship/repo/fedora-%OS_VERSION%/atim-starship-fedora-%OS_VERSION%.repo install: - python3-pip # required for yafti @@ -40,4 +53,5 @@ modules: - type: script scripts: # this sets up the proper policy & signing files for signed images to work - - signing.sh \ No newline at end of file + - signing.sh + diff --git a/modules/bling/README.md b/modules/bling/README.md index e342c4a5d0..c76fa71c6f 100644 --- a/modules/bling/README.md +++ b/modules/bling/README.md @@ -1,10 +1,11 @@ -# [`bling`](https://github.com/ublue-os/bling) module for startingpoint +# [`bling`](https://github.com/ublue-os/bling) Module for Startingpoint The `bling` module allows you to easily declare which general parts of `ublue-os/bling` to pull in to your custom image. It requires the `rpms` and `files` directories from the `bling` container to already exist inside `/tmp/bling/` (pulled inside the Containerfile by default). The blingbling to pull in is declared under `install:`, and the code for installing them is all in simple named scripts under the `installers/` directory. The basic code for the `bling` module is very similar to the code of the `script` module. -Example configuration: +## Example configuration: + ```yml type: bling # configure what to pull in from ublue-os/bling install: @@ -16,4 +17,4 @@ install: # - ublue-update # https://github.com/ublue-os/ublue-update # - dconf-update-service # a service unit that updates the dconf db on boot # - devpod # https://devpod.sh/ as an rpm -``` \ No newline at end of file +``` diff --git a/modules/files/README.md b/modules/files/README.md new file mode 100644 index 0000000000..7e1e7d17dd --- /dev/null +++ b/modules/files/README.md @@ -0,0 +1,16 @@ +# `files` Module for Startingpoint + +The `files` module simplifies the process of copying files to the image during the build time. These files are sourced from the `config/files` directory, which is located at `/tmp/config/files` inside the image. + +> **Warning** +> If you want to place anything in `/etc` of the final image, you MUST place them in `/usr/etc` in your repo, so that they're written to `/usr/etc` on the final system. That is the proper directory for "system" configuration templates on immutable Fedora distros, whereas the normal `/etc` is ONLY meant for manual overrides and editing by the machine's admin AFTER installation! See issue https://github.com/ublue-os/startingpoint/issues/28. + +## Example Configuration: + +```yaml +type: files +files: + usr: /usr +``` + +In the example above, `usr` represents the directory located inside the `config/files` in the repository, while `/usr` designates the corresponding destination within the image. diff --git a/modules/files/files.sh b/modules/files/files.sh new file mode 100644 index 0000000000..8320dbc19b --- /dev/null +++ b/modules/files/files.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# Tell build process to exit if there are any errors. +set -oue pipefail + +get_yaml_array FILES '.files[]' "$1" + +cd "$CONFIG_DIRECTORY/files" + +if [[ ${#FILES[@]} -gt 0 ]]; then + echo "Adding files to image" + for pair in "${FILES[@]}"; do + FILE="$PWD/$(echo $pair | yq 'to_entries | .[0].key')" + DEST=$(echo $pair | yq 'to_entries | .[0].value') + if [ -d "$FILE" ]; then + if [ ! -d "$DEST" ]; then + mkdir -p "$DEST" + fi + echo "Copying $FILE to $DEST" + cp -r "$FILE"/* $DEST + elif [ -f "$FILE" ]; then + DEST_DIR=$(dirname "$DEST") + if [ ! -d "$DEST_DIR" ]; then + mkdir -p "$DEST_DIR" + fi + echo "Copying $FILE to $DEST" + cp $FILE $DEST + else + echo "File or Directory $FILE Does Not Exist in $CONFIG_DIRECTORY/files" + exit 1 + fi + done +fi diff --git a/modules/rpm-ostree/README.md b/modules/rpm-ostree/README.md index 469b8ffd36..c1baf5753f 100644 --- a/modules/rpm-ostree/README.md +++ b/modules/rpm-ostree/README.md @@ -1,4 +1,4 @@ -# [`rpm-ostree`](https://coreos.github.io/rpm-ostree/) module for startingpoint +# [`rpm-ostree`](https://coreos.github.io/rpm-ostree/) Module for Startingpoint The `rpm-ostree` module offers pseudo-declarative package and repository management using `rpm-ostree`. @@ -6,14 +6,13 @@ The module first downloads the repository files from repositories declared under Then the module installs the packages declared under `install:` using `rpm-ostree install`, and lastly, it removes the packages declared under `remove:` using `rpm-ostree override remove`. -Unfortunately, currently `rpm-ostree override remove`, and this module, might not be able to remove packages installed in image builds. Packages included by Fedora, such as Firefox can still be removed, though. - Additionally, the `rpm-ostree` module supports a temporary (waiting for `rpm-ostree` issue [#233](https://github.com/coreos/rpm-ostree/issues/233)) fix for packages that install into `/opt/`. Installation for packages that install into folder names declared under `optfix:` are fixed using some symlinks. - -Example configuration: + +## Example Configuration: + ```yml type: rpm-ostree -repos: +repos: - https://copr.fedorainfracloud.org/coprs/atim/starship/repo/fedora-%OS_VERSION%/atim-starship-fedora-%OS_VERSION%.repo install: - python3-pip @@ -21,4 +20,4 @@ install: remove: - firefox - firefox-langpacks -``` \ No newline at end of file +``` diff --git a/modules/script/README.md b/modules/script/README.md index 0be8b52f25..b2419c50e4 100644 --- a/modules/script/README.md +++ b/modules/script/README.md @@ -1,15 +1,17 @@ -# `script` module for startingpoint +# `script` Module for Startingpoint The `script` module can be used to run arbitrary scripts at image build time that take no or minimal external configuration (in the form of command line arguments). The scripts, which are run from the `config/scripts` directory, are declared under `scripts:`. +## Example Configuration + ```yml type: script scripts: - signing.sh ``` -## Creating a script +## Creating a Script Look at `example.sh` for an example shell script. You can rename and copy the file for your own purposes. In order for the script to be executed, declare it in the recipe @@ -21,4 +23,4 @@ When creating a script, please make sure - ...it starts with a [shebang]() like `#!/usr/bin/env bash`. - This ensures the script is ran with the correct interpreter / shell. - ...it contains the command `set -oue pipefail` near the start. - - This will make the image build fail if your script fails. If you do not care if your script works or not, you can omit this line. \ No newline at end of file + - This will make the image build fail if your script fails. If you do not care if your script works or not, you can omit this line. diff --git a/modules/systemd/README.md b/modules/systemd/README.md new file mode 100644 index 0000000000..4b122b84be --- /dev/null +++ b/modules/systemd/README.md @@ -0,0 +1,41 @@ +# `systemd` Module for Startingpoint + +The `systemd` module streamlines the management of systemd units during image building. Units are divided into `system` and `user` categories, with `system` units managed directly using `systemctl` and `user` units using `systemctl --user`. You can specify which units to enable or disable under each category. + +## Example Configuration: + +```yaml +type: systemd +system: + enable: + - example.service + disable: + - example.target +user: + enable: + - example.timer + disable: + - example.service +``` + +In this example: + +### System Units +- `example.service`: Enabled (runs on system boot) +- `example.target`: Disabled (does not run on system boot) + +### User Units +- `example.timer`: Enabled (runs for the user) +- `example.service`: Disabled (does not run for the user) + +This configuration achieves the same results as the following commands: + +```sh +# System Units +systemctl enable example.service +systemctl disable example.target + +# User Units +systemctl --user enable example.timer +systemctl --user disable example.service +``` diff --git a/modules/systemd/systemd.sh b/modules/systemd/systemd.sh new file mode 100644 index 0000000000..a9aeb5e730 --- /dev/null +++ b/modules/systemd/systemd.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +# Tell build process to exit if there are any errors. +set -oue pipefail + +get_yaml_array ENABLED '.system.enabled[]' "$1" +get_yaml_array DISABLED '.system.disabled[]' "$1" +get_yaml_array USER_ENABLED '.user.enabled[]' "$1" +get_yaml_array USER_DISABLED '.user.disabled[]' "$1" + + +if [[ ${#ENABLED[@]} -gt 0 ]]; then + for unit in "${ENABLED[@]}"; do + unit=$(printf "$unit") + systemctl enable $unit + done +fi +if [[ ${#DISABLED[@]} -gt 0 ]]; then + for unit in "${DISABLED[@]}"; do + unit=$(printf "$unit") + systemctl disable $unit + done +fi +if [[ ${#USER_ENABLED[@]} -gt 0 ]]; then + for unit in "${ENABLED[@]}"; do + unit=$(printf "$unit") + systemctl --user enable $unit + done +fi +if [[ ${#USER_DISABLED[@]} -gt 0 ]]; then + for unit in "${DISABLED[@]}"; do + unit=$(printf "$unit") + systemctl --user disable $unit + done +fi diff --git a/modules/yafti/README.md b/modules/yafti/README.md index de318b67f7..a67cf0d95c 100644 --- a/modules/yafti/README.md +++ b/modules/yafti/README.md @@ -1,4 +1,4 @@ -# [`yafti`](https://github.com/ublue-os/yafti) module for startingpoint +# [`yafti`](https://github.com/ublue-os/yafti) Module for Startingpoint If included, the `yafti` module will install `yafti` and set it up to run on first boot. @@ -6,10 +6,11 @@ Optionally, a list of Flatpak names and IDs can be included under `custom-flatpa The main `yafti` configuration file, `yafti.yml`, is in `/usr/share/ublue-os/firstboot/yafti.yml` and can be edited for a more custom first-boot experience. -Example configuration: +## Example configuration: + ```yml type: yafti custom-flatpaks: - Celluloid: io.github.celluloid_player.Celluloid - Krita: org.kde.krita -``` \ No newline at end of file +```