Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
feat: added systemd and files module (#142)
Browse files Browse the repository at this point in the history
* feat: add files and systemd module

* fix: yaml formatting

* fix: yaml formatting

* fix: remove comment completely

* fix: yaml formatting

* docs: add back inline comment

* reformat: rename variables

* fix: fix systemd escaped string

* fix: fix systemd service formatting with printf

* fix: attempting to fix systemd module problems

* chore: remove debug config and code from systemd module

* docs: added WIP docs for systemd, reworked files README

* docs: added more detail for systemd module

* docs: update READMEs to be more consistent

* docs: remove unneeded sentence

* docs: remove unneeded sentence

* chore: fix issues described in PR review

* docs: fix markdown formatting

* docs: fix markdown formatting

* docs: better markdown
  • Loading branch information
gerblesh authored Sep 5, 2023
1 parent eb37ec3 commit cc90a91
Show file tree
Hide file tree
Showing 18 changed files with 164 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -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.


Expand Down
11 changes: 1 addition & 10 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -53,4 +53,4 @@ for MODULE in "${MODULES[@]}"; do
bash "$MODULE_DIRECTORY/$TYPE/$TYPE.sh" "$MODULE_CONFIG"
fi
echo "======"
done
done
18 changes: 16 additions & 2 deletions config/recipe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -40,4 +53,5 @@ modules:
- type: script
scripts:
# this sets up the proper policy & signing files for signed images to work
- signing.sh
- signing.sh

7 changes: 4 additions & 3 deletions modules/bling/README.md
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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
```
```
16 changes: 16 additions & 0 deletions modules/files/README.md
Original file line number Diff line number Diff line change
@@ -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.
33 changes: 33 additions & 0 deletions modules/files/files.sh
Original file line number Diff line number Diff line change
@@ -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
13 changes: 6 additions & 7 deletions modules/rpm-ostree/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# [`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`.

The module first downloads the repository files from repositories declared under `repos:` into `/etc/yum.repos.d/`. The magic string `%OS_VERSION%` is substituted with the current VERSION_ID (major Fedora version), which can be used, for example, for pulling correct versions of repositories from [Fedora's Copr](https://copr.fedorainfracloud.org/).

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
- libadwaita
remove:
- firefox
- firefox-langpacks
```
```
8 changes: 5 additions & 3 deletions modules/script/README.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -21,4 +23,4 @@ When creating a script, please make sure
- ...it starts with a [shebang](<https://en.wikipedia.org/wiki/Shebang_(Unix)>) 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.
- 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.
41 changes: 41 additions & 0 deletions modules/systemd/README.md
Original file line number Diff line number Diff line change
@@ -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
```
35 changes: 35 additions & 0 deletions modules/systemd/systemd.sh
Original file line number Diff line number Diff line change
@@ -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
7 changes: 4 additions & 3 deletions modules/yafti/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# [`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.

Optionally, a list of Flatpak names and IDs can be included under `custom-flatpaks:`. These will be enabled by default under their own section on the Flatpak installation screen of `yafti`.

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
```
```

0 comments on commit cc90a91

Please sign in to comment.