Skip to content

Commit

Permalink
Reorganize eext base image boostrap code
Browse files Browse the repository at this point in the history
Separate out bootstrap code in barney.yaml to three parts in three
different scripts:
1. Extract(boostrap/extract/extract.bash): Extracting bootstrap image from the tarball.
2. Setup dnf configuration(bootstrap/eext-repos/generate.bash): dnf
   configuration for both base image bootstrap and for install within
   base-image is done by this stage.
3. Install rpms(bootstrap/install-rpms/install-rpms.bash): The old
   install-rpms script is now reading rpms to be installed from the
   source files rpms-common and rpms-<conf> in the
   bootstrap/install-rpms directory.

Also added a base-image-devel ref to be used by developers for
interactive workflow.
  • Loading branch information
aajith-arista committed Jul 23, 2024
1 parent 6854598 commit c131041
Show file tree
Hide file tree
Showing 19 changed files with 557 additions and 95 deletions.
178 changes: 109 additions & 69 deletions barney.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,22 @@ generators:

images:

internal/bootstrap/iso-extraction-floor:
internal/bootstrap/extract-floor:
entry:
mutables:
- /var/work
units:
- image: barney.ci/alpine%pkg/alpine-base
- image: barney.ci/alpine%pkg/gettext
- image: barney.ci/alpine%pkg/bash
- image: barney.ci/alpine%pkg/wget
- image: barney.ci/alpine%network
- image: barney.ci/alpine%apk-finalizers
- build: |
mkdir -p /dest/var/work
cp -a bootstrap/extract /dest
internal/bootstrap/src-deps:
internal/bootstrap/extract:
no-create-mountpoints: true
units:
- build: |
cp -a bootstrap/* /dest/
cp -a pki/rpmkeys/alma9-b86b3716-gpg-pubkey.pem /dest/
cp -a pki/rpmkeys/epel9-3228467c-gpg-pubkey.pem /dest/
rm -f /dest/README*
internal/bootstrap:
description: |
Minimal bootstrapping environment used to bootstrap almalinux.
Expand All @@ -36,11 +29,7 @@ images:
is readily available on the mirror. This is seldom changed and
any change here will update all eext snapshots.
We wipe out the dnf/yum repo configuration in the tarball,
and setup our own curated set of frozen almalinux repos.
We also include an install-rpms script which is used to bootstrap
the almalinux image.
We wipe out the dnf/yum repo configuration in the tarball.
entry:
share-net: true
mounts:
Expand All @@ -51,65 +40,105 @@ images:
- /var/cache
- /var/lib/dnf
units:
- floor: .%internal/bootstrap/iso-extraction-floor
- floor: .%internal/bootstrap/extract-floor
entry:
env:
DNF_HOST: ${eext-dnf-host.url:-https://artifactory.infra.corp.arista.io/artifactory}
BOOTSTRAP_PATH: eext-sources/bootstrap/CentOS-Stream
BOOTSTRAP_FILE: CentOS-Stream-Container-Base-9-20240715.0
BOOTSTRAP_EXTENSION: tar.xz
DNF_DISTRO_REPO: eext-alma-vault
DNF_DISTRO_REPO_VERSION: "9.3"
DNF_EPEL_REPO: eext-snapshots-local/epel9
DNF_EPEL_REPO_SNAPSHOT_VERSION: v20240127-1
DNF_EPEL_REPO_DISTRO_VERSION: "9"
sources: []
mappings:
/src/bootstrap: .%internal/bootstrap/src-deps
build: |
# URL of tarball with OS image
export ARCH=$(uname -m)
bootstrap_filename="${BOOTSTRAP_FILE}.${ARCH}.${BOOTSTRAP_EXTENSION}"
bootstrap_url="${DNF_HOST}/${BOOTSTRAP_PATH}/${bootstrap_filename}"
cd /var/work
/extract/extract.bash /extract
touch $DESTDIR/etc/resolv.conf
# Download the tarball into the mutable working dir
internal/bootstrap/eext-repos-floor:
description: |
Alpine floor with the eext-repos src directory mapped in.
gettext provides envsubst used by generate-repo-file.bash called from generate.bash
rpm-dev provides rpmbuild used by generate.bash.
entry:
mutables:
- /var/work
- /var/tmp
units:
- image: barney.ci/alpine%pkg/alpine-base
- image: barney.ci/alpine%pkg/bash
- image: barney.ci/alpine%pkg/gettext
- image: barney.ci/alpine%pkg/rpm-dev
- image: barney.ci/alpine%apk-finalizers
- build: |
mkdir -p /dest/var/work
cp -a bootstrap/eext-repos /dest
cp -a pki/rpmkeys/alma9-b86b3716-gpg-pubkey.pem /dest/eext-repos
cp -a pki/rpmkeys/epel9-3228467c-gpg-pubkey.pem /dest/eext-repos
internal/bootstrap/eext-repos:
no-create-mountpoints: true
description: |
Setup curated frozen dnf repo list for build reproducibility.
There're two files, eext-repo-build.repo and eext-repo-devel.repo. These files are
installed in /eext-repos directory.
We also install the eext-repo-build.repo in /etc/yum.repos.d to be used for base image
bootstrap.
We also build an rpm each with the contents being the repo file,
and instructions to install at /etc/yum.repos.d.
The RPMs are named eext-repos-build and eext-repos-devel with approiate architecture
and .rpm extensions. They are installed in /RPMS.
units:
- floor: .%internal/bootstrap/eext-repos-floor
entry:
env:
DNF_HOST: ${eext-dnf-host.url:-https://artifactory.infra.corp.arista.io/artifactory}
sources: []
build: |
cd /var/work
wget ${bootstrap_url}
# Validate downloaded tarball
grep "${bootstrap_filename}" /src/bootstrap/CHECKSUM | sha256sum -wc
# Extract tarball and setup rootfs
# This is a nested tarball, the real rootfs is in layer.tar
# Extract the firt level tarball inside the extr subdirectory
# within the working directory and and then extract the
# second level layer.tar directly to /dest
mkdir extr
tar --strip-components=1 -C ./extr -xf ./${bootstrap_filename}
tar -xf ./extr/layer.tar -C /dest
# Now modify the extracted file system to remove unwanted
# stuff and add extra stuff.
# Remove any pre-configured yum repos
rm /dest/etc/yum.repos.d/*
# Setup install-rpms shell script
mkdir -p /dest/usr/bin
chmod 555 /dest/usr/bin
cp -a /src/bootstrap/install-rpms /dest/usr/bin/
chmod 0755 /dest/usr/bin/install-rpms
# Setup gpg keys
mkdir -p /dest/usr/share/distribution-gpg-keys
chmod 555 /dest/usr/share/distribution-gpg-keys
cp -a /src/bootstrap/*.pem /dest/usr/share/distribution-gpg-keys/
# Setup curated frozen dnf repo list for build reproducibility
envsubst < /src/bootstrap/eext-repos-build.repo.template > /dest/etc/yum.repos.d/eext-repos-build.repo
base-image:
/eext-repos/generate.bash /eext-repos
internal/bootstrap/install-rpms:
no-create-mountpoints: true
description: |
Setup install-rpm scripts and collaterals for bootstrapping
units:
- build: |
cp -a bootstrap/install-rpms /dest
internal/bootstrap/dnf-dirs:
no-create-mountpoints: true
description: |
Setup empty directories needed by dnf
units:
- sources: []
build: |
mkdir -p /dest/var/lib/dnf
chmod 755 /dest/var/lib/dnf
internal/bootstrap:
description: |
Final bootstrap layer used as floor to build base images.
units:
- image: .%internal/bootstrap/dnf-dirs
- image: .%internal/bootstrap/extract
- image: .%internal/bootstrap/eext-repos
- image: .%internal/bootstrap/install-rpms

base-image-build:
units:
- floor: .%internal/bootstrap
sources: []
build: |
echo "install rpms"
/install-rpms/install-rpms.bash \
--common-rpms-file /install-rpms/rpms-common \
--extra-rpms-file /install-rpms/rpms-build
base-image-devel:
units:
- floor: .%internal/bootstrap
sources: []
build: install-rpms autoconf automake coreutils git rpm rpmdevtools rpm-build make mock python3-devel quilt
build: |
/install-rpms/install-rpms.bash \
--common-rpms-file /install-rpms/rpms-common \
--extra-rpms-file /install-rpms/rpms-devel
go-binaries:
description: |
Expand All @@ -124,17 +153,25 @@ images:
cp -a /src/static/usr/bin /dest/usr/bin
chmod 555 /dest/usr/bin
eext:
eext-configfiles:
units:
- image: .%base-image
- image: .%go-binaries
- build: |
mkdir -p $DESTDIR/usr/share/eext
cp -a ./configfiles/* $DESTDIR/usr/share/eext
mkdir -p $DESTDIR/etc/pki/eext
cp -a ./pki/* $DESTDIR/etc/pki/eext
mkdir -p $DESTDIR/etc
touch $DESTDIR/etc/resolv.conf
eext:
units:
- image: .%base-image-build
- image: .%go-binaries
- image: .%eext-configfiles
- build: |
mkdir -p $DESTDIR/etc
touch $DESTDIR/etc/resolv.conf
entry:
mutables: &eext-mutables
- /var/eext
Expand All @@ -159,8 +196,11 @@ images:
- floor: .%internal/bootstrap
sources: []
build: |
install-rpms autoconf automake coreutils golang git rpm rpmdevtools rpm-build make mock python3-devel quilt
/install-rpms/install-rpms.bash \
--common-rpms-file /install-rpms/rpms-common \
--extra-rpms-file /install-rpms/rpms-devel
touch $DESTDIR/etc/resolv.conf
entry:
env:
GOCACHE: /tmp/gocache
Expand Down
53 changes: 50 additions & 3 deletions bootstrap/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
# Uploading Bootstrap Tarball
# Bootstrapping a Redhat based distro image for the eext tool

This document explains how a base image for eext buids or development workflow is built. The base image should contain the utilties called by the eext static go binary.
The main dependencies are rpm, rpmbuild and mock.
We support two base images, one for running eext builds in Abuilds/bsy builds, and another for running eext builds in an user's interactive development environment. We call them base-image-build and base-image-devel.


## Bootstrap image
We need a RPM based rootfs to boostrap the eext base image which is today based of AlmaLinux.
We construct this rootfs image form a tarball published by some RPM based distro.
We need a tarball per target-arch, ie x86_64 amd aarch64. Note that i686 RPMs are built with the x86_64 eext base image itself.
This bootstrap tarball need not be AlmaLinux, it can be any RPM based distro. We're using a CentOS Stream tarball for this purpose, because they publish it to the mirror with checksums.

### Updating/Uploading the bootstrap tarball

1. Download a CentOS-Stream-Container-Base tarball with a timestamp in its name, like `20230704`, from:
- [https://cloud.centos.org/centos/9-stream/x86_64/images/](https://cloud.centos.org/centos/9-stream/x86_64/images/)
Expand All @@ -7,7 +20,41 @@
```
curl -H "Authorization: Bearer ${ARTIFACTORY_TOKEN}" -X PUT https://artifactory.infra.corp.arista.io/artifactory/eext-sources/bootstrap/CentOS-Stream/ -T <TARBALL_PATH>
```
3. Update the `CHECKSUM` file in the local repo for the new entries from the `CHECKSUM` files:
3. Update the `extract/CHECKSUM` file in the local repo for the new entries from the `CHECKSUM` files:
- [https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM](https://cloud.centos.org/centos/9-stream/x86_64/images/CHECKSUM)
- [https://cloud.centos.org/centos/9-stream/aarch64/images/CHECKSUM](https://cloud.centos.org/centos/9-stream/aarch64/images/CHECKSUM)
4. Update the `EEXT_BOOTSTRAP_VERSION` environment variable in `barney.yaml`.
4. Update the `bootstrap_filename_version` variable in `extract/extract.bash`.

## Base Image Build

### Repo configuration
To build an AlmaLinux base-image we run `dnf --installroot` inside the bootstrap image. We maintain our own curated dnf configuration on the `eext-repos` directory.
The configuration points to the second most recent dot release of the main AlmaLinux that eext is tracking. The idea is that this vaulted and frozen, giving us reproducible builds.
Note that we make them point to a local artifactory remote-repo/mirror of the upstream AlmaLinux repo. This makes sure we don't have unnecessary internet traffic, and we have a copy of the dependencies maintained in the remote repo's cache.

We maintain two such configuration file templates in our source for each variant of the base image:
1 `eext-repos/eext-repos-build.repo.template`
2.`eext-repos/eext-repos-devel.repo.template`

The build specific configuration just includes the basic repos needed for satisfying the the eext dependencies like `rpm` and `mock`.
The development configuration configures a superset of the build configuration, because the developer might need to install more tools like editors etc.
We try to track the major/minor versions of the distros similarly between the two. The `eext-repos/repos-common.env` file holds the versions, actual repo names, URLs etc as environment variables.

We want the build specific repos to point to the `eext-alma-vault` artifactory remote repo, while we point the development repos to the the global `alma-vault` remote repository.
This makes sure that the dependencies in the developer's environment don't pollute `eext-alma-vault` cache.
The base-image specific configuration exists in the `eext-repos/repos-build.env` and `eext-repos/repos-devel.env` files.

The `eext-repos/generate.bash` script loads the `.env` files and builds the actual repo configuration files from the templates.

Note that we need repo configuration in two stages:
1. For the boostrap container for base-image generation
2. Repo configuration in the base image itself.

Note that the distinction in the repo configuration exists only for `2`. The bootstrap container is always configured with the build variant.
The developer just uses these repos to further install further packages in his bus or docker container with dnf.

### Base Image Contents
Once the bootstrap image and repo configuration is ready, we run the `install-rpms/install-rpms.bash` script to build the base image.
The set of rpms to be installed is specified in the text files: `install-rpms/rpms-common`, `install-rpms/rpms-build` and `install-rpms/rpms-devel`.
The `install-rpms` script takes two arguments, `--common-rpms-file rpms-common` and `--extra-rpms-file (rpms-build | rpms-devel)`.

16 changes: 0 additions & 16 deletions bootstrap/eext-repos-build.repo.template

This file was deleted.

16 changes: 16 additions & 0 deletions bootstrap/eext-repos/eext-repos-build.repo.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[baseos]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/BaseOS/${ARCH}/os/
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[appstream]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/AppStream/${ARCH}/os/
exclude=podman
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[epel9-snapshot]
baseurl=${DNF_HOST}/${DNF_EPEL_SNAPSHOT_REPO}/${DNF_EPEL_SNAPSHOT_REPO_VERSION}/${DNF_EPEL_DISTRO_VERSION}/Everything/${ARCH}/
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/epel9-3228467c-gpg-pubkey.pem

37 changes: 37 additions & 0 deletions bootstrap/eext-repos/eext-repos-devel.repo.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[baseos]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/BaseOS/${ARCH}/os/
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[appstream]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/AppStream/${ARCH}/os/
exclude=podman
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[epel9-snapshot]
baseurl=${DNF_HOST}/${DNF_EPEL_SNAPSHOT_REPO}/${DNF_EPEL_SNAPSHOT_REPO_VERSION}/${DNF_EPEL_DISTRO_VERSION}/Everything/${ARCH}/
enabled=1
gpgkey=file:///usr/share/eext-gpg-keys/epel9-3228467c-gpg-pubkey.pem

[crb]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/CRB/${ARCH}/os/
enabled=0
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[devel]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/devel/${ARCH}/os/
enabled=0
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[extras]
baseurl=${DNF_HOST}/${DNF_DISTRO_REPO}/${DNF_DISTRO_REPO_VERSION}/extras/${ARCH}/os/
enabled=0
gpgkey=file:///usr/share/eext-gpg-keys/alma9-b86b3716-gpg-pubkey.pem

[epel]
baseurl=${DNF_HOST}/${DNF_EPEL_REPO}/${ARCH}/
enabled=0
exclude=mock
gpgkey=file:///usr/share/eext-gpg-keys/epel9-3228467c-gpg-pubkey.pem

Loading

0 comments on commit c131041

Please sign in to comment.