From 3c4c613a1a2b68ffc89274c77cd745380fd844c1 Mon Sep 17 00:00:00 2001 From: Neil Hanlon Date: Wed, 15 Nov 2023 12:46:25 -0700 Subject: [PATCH] make docker happen --- 9-container.yml | 8 + 9-minimal.yml | 2 +- elements/rocky-container-base/README.rst | 9 + elements/rocky-container-base/element-deps | 1 + .../rocky-container-base/element-provides | 1 + .../environment.d/10-rocky-distro-name.bash | 3 + .../environment.d/11-yum-dnf.bash | 2 + .../test-elements/build-succeeds/README.rst | 1 + .../test-elements/build-succeeds/element-deps | 2 + .../rocky-container-base/yum.repos.d/yum.repo | 17 + elements/rocky-genericcloud/README.rst | 9 + elements/rocky-genericcloud/element-deps | 1 + elements/rocky-genericcloud/element-provides | 1 + .../environment.d/10-rocky-distro-name.bash | 3 + .../environment.d/11-yum-dnf.bash | 2 + .../test-elements/build-succeeds/README.rst | 1 + .../test-elements/build-succeeds/element-deps | 2 + .../rocky-genericcloud/yum.repos.d/yum.repo | 17 + elements/rocky-minimal-yum/README.rst | 29 ++ .../cleanup.d/95-remove-yum-mirror | 35 ++ elements/rocky-minimal-yum/element-deps | 3 + .../install.d/10-base-networking | 44 ++ .../install.d/11-ensure-dbus-daemon | 28 ++ .../rocky-minimal-yum/package-installs.yaml | 22 + elements/rocky-minimal-yum/pkg-map | 7 + .../pre-install.d/03-yum-cleanup | 84 ++++ .../rocky-minimal-yum/root.d/08-yum-chroot | 416 ++++++++++++++++++ 27 files changed, 749 insertions(+), 1 deletion(-) create mode 100644 9-container.yml create mode 100644 elements/rocky-container-base/README.rst create mode 100644 elements/rocky-container-base/element-deps create mode 100644 elements/rocky-container-base/element-provides create mode 100644 elements/rocky-container-base/environment.d/10-rocky-distro-name.bash create mode 100644 elements/rocky-container-base/environment.d/11-yum-dnf.bash create mode 100644 elements/rocky-container-base/test-elements/build-succeeds/README.rst create mode 100644 elements/rocky-container-base/test-elements/build-succeeds/element-deps create mode 100644 elements/rocky-container-base/yum.repos.d/yum.repo create mode 100644 elements/rocky-genericcloud/README.rst create mode 100644 elements/rocky-genericcloud/element-deps create mode 100644 elements/rocky-genericcloud/element-provides create mode 100644 elements/rocky-genericcloud/environment.d/10-rocky-distro-name.bash create mode 100644 elements/rocky-genericcloud/environment.d/11-yum-dnf.bash create mode 100644 elements/rocky-genericcloud/test-elements/build-succeeds/README.rst create mode 100644 elements/rocky-genericcloud/test-elements/build-succeeds/element-deps create mode 100644 elements/rocky-genericcloud/yum.repos.d/yum.repo create mode 100644 elements/rocky-minimal-yum/README.rst create mode 100755 elements/rocky-minimal-yum/cleanup.d/95-remove-yum-mirror create mode 100644 elements/rocky-minimal-yum/element-deps create mode 100755 elements/rocky-minimal-yum/install.d/10-base-networking create mode 100755 elements/rocky-minimal-yum/install.d/11-ensure-dbus-daemon create mode 100644 elements/rocky-minimal-yum/package-installs.yaml create mode 100644 elements/rocky-minimal-yum/pkg-map create mode 100755 elements/rocky-minimal-yum/pre-install.d/03-yum-cleanup create mode 100755 elements/rocky-minimal-yum/root.d/08-yum-chroot diff --git a/9-container.yml b/9-container.yml new file mode 100644 index 0000000..f21600a --- /dev/null +++ b/9-container.yml @@ -0,0 +1,8 @@ +- imagename: Rocky-9-Container + types: [tgz] + docker-target: git.resf.org/sig_cloud/images:9.3 + elements: [rocky-container-base] + arch: ppc64le + environment: + DIB_ARCHITECTURE: ppc64le + DIB_YUM_DNF_CONTENTDIR: stg/rocky diff --git a/9-minimal.yml b/9-minimal.yml index 40f3341..76ffcbb 100644 --- a/9-minimal.yml +++ b/9-minimal.yml @@ -1,5 +1,5 @@ - imagename: output.qcow - elements: [vm, block-device-gpt, rocky-minimal] + elements: [vm, block-device-gpt, rocky-genericcloud] arch: ppc64le debug-trace: 1 environment: diff --git a/elements/rocky-container-base/README.rst b/elements/rocky-container-base/README.rst new file mode 100644 index 0000000..93356e2 --- /dev/null +++ b/elements/rocky-container-base/README.rst @@ -0,0 +1,9 @@ +============== +rocky-minimal +============== + +Create a minimal image based on Rocky. + +This element sets the ``DISTRO_NAME`` var to 'rocky'. The release of +rocky to be installed can be controlled through the ``DIB_RELEASE`` +variable, which defaults the latest supported release. diff --git a/elements/rocky-container-base/element-deps b/elements/rocky-container-base/element-deps new file mode 100644 index 0000000..7f5e0ff --- /dev/null +++ b/elements/rocky-container-base/element-deps @@ -0,0 +1 @@ +rocky-minimal-yum diff --git a/elements/rocky-container-base/element-provides b/elements/rocky-container-base/element-provides new file mode 100644 index 0000000..a72e049 --- /dev/null +++ b/elements/rocky-container-base/element-provides @@ -0,0 +1 @@ +operating-system diff --git a/elements/rocky-container-base/environment.d/10-rocky-distro-name.bash b/elements/rocky-container-base/environment.d/10-rocky-distro-name.bash new file mode 100644 index 0000000..fbf1a63 --- /dev/null +++ b/elements/rocky-container-base/environment.d/10-rocky-distro-name.bash @@ -0,0 +1,3 @@ +export DISTRO_NAME=rocky +export DIB_RELEASE=${DIB_RELEASE:-9} +export EFI_BOOT_DIR="EFI/rocky" diff --git a/elements/rocky-container-base/environment.d/11-yum-dnf.bash b/elements/rocky-container-base/environment.d/11-yum-dnf.bash new file mode 100644 index 0000000..ab2f718 --- /dev/null +++ b/elements/rocky-container-base/environment.d/11-yum-dnf.bash @@ -0,0 +1,2 @@ +export YUM=dnf +export DNF_VAR_contentdir=stg/rocky diff --git a/elements/rocky-container-base/test-elements/build-succeeds/README.rst b/elements/rocky-container-base/test-elements/build-succeeds/README.rst new file mode 100644 index 0000000..0a6c77e --- /dev/null +++ b/elements/rocky-container-base/test-elements/build-succeeds/README.rst @@ -0,0 +1 @@ +Verify we can build a rocky-minimal image. diff --git a/elements/rocky-container-base/test-elements/build-succeeds/element-deps b/elements/rocky-container-base/test-elements/build-succeeds/element-deps new file mode 100644 index 0000000..6d1fc8b --- /dev/null +++ b/elements/rocky-container-base/test-elements/build-succeeds/element-deps @@ -0,0 +1,2 @@ +block-device-gpt +vm diff --git a/elements/rocky-container-base/yum.repos.d/yum.repo b/elements/rocky-container-base/yum.repos.d/yum.repo new file mode 100644 index 0000000..ac3cc16 --- /dev/null +++ b/elements/rocky-container-base/yum.repos.d/yum.repo @@ -0,0 +1,17 @@ +[baseos] +name=Rocky Linux $releasever - BaseOS - STG +baseurl=http://dl.rockylinux.org/stg/rocky/$releasever/BaseOS/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 + +[appstream] +name=Rocky Linux $releasever - AppStream +baseurl=http://dl.rockylinux.org/stg/rocky/$releasever/AppStream/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 diff --git a/elements/rocky-genericcloud/README.rst b/elements/rocky-genericcloud/README.rst new file mode 100644 index 0000000..93356e2 --- /dev/null +++ b/elements/rocky-genericcloud/README.rst @@ -0,0 +1,9 @@ +============== +rocky-minimal +============== + +Create a minimal image based on Rocky. + +This element sets the ``DISTRO_NAME`` var to 'rocky'. The release of +rocky to be installed can be controlled through the ``DIB_RELEASE`` +variable, which defaults the latest supported release. diff --git a/elements/rocky-genericcloud/element-deps b/elements/rocky-genericcloud/element-deps new file mode 100644 index 0000000..752a479 --- /dev/null +++ b/elements/rocky-genericcloud/element-deps @@ -0,0 +1 @@ +yum-minimal diff --git a/elements/rocky-genericcloud/element-provides b/elements/rocky-genericcloud/element-provides new file mode 100644 index 0000000..a72e049 --- /dev/null +++ b/elements/rocky-genericcloud/element-provides @@ -0,0 +1 @@ +operating-system diff --git a/elements/rocky-genericcloud/environment.d/10-rocky-distro-name.bash b/elements/rocky-genericcloud/environment.d/10-rocky-distro-name.bash new file mode 100644 index 0000000..fbf1a63 --- /dev/null +++ b/elements/rocky-genericcloud/environment.d/10-rocky-distro-name.bash @@ -0,0 +1,3 @@ +export DISTRO_NAME=rocky +export DIB_RELEASE=${DIB_RELEASE:-9} +export EFI_BOOT_DIR="EFI/rocky" diff --git a/elements/rocky-genericcloud/environment.d/11-yum-dnf.bash b/elements/rocky-genericcloud/environment.d/11-yum-dnf.bash new file mode 100644 index 0000000..ab2f718 --- /dev/null +++ b/elements/rocky-genericcloud/environment.d/11-yum-dnf.bash @@ -0,0 +1,2 @@ +export YUM=dnf +export DNF_VAR_contentdir=stg/rocky diff --git a/elements/rocky-genericcloud/test-elements/build-succeeds/README.rst b/elements/rocky-genericcloud/test-elements/build-succeeds/README.rst new file mode 100644 index 0000000..0a6c77e --- /dev/null +++ b/elements/rocky-genericcloud/test-elements/build-succeeds/README.rst @@ -0,0 +1 @@ +Verify we can build a rocky-minimal image. diff --git a/elements/rocky-genericcloud/test-elements/build-succeeds/element-deps b/elements/rocky-genericcloud/test-elements/build-succeeds/element-deps new file mode 100644 index 0000000..6d1fc8b --- /dev/null +++ b/elements/rocky-genericcloud/test-elements/build-succeeds/element-deps @@ -0,0 +1,2 @@ +block-device-gpt +vm diff --git a/elements/rocky-genericcloud/yum.repos.d/yum.repo b/elements/rocky-genericcloud/yum.repos.d/yum.repo new file mode 100644 index 0000000..ac3cc16 --- /dev/null +++ b/elements/rocky-genericcloud/yum.repos.d/yum.repo @@ -0,0 +1,17 @@ +[baseos] +name=Rocky Linux $releasever - BaseOS - STG +baseurl=http://dl.rockylinux.org/stg/rocky/$releasever/BaseOS/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 + +[appstream] +name=Rocky Linux $releasever - AppStream +baseurl=http://dl.rockylinux.org/stg/rocky/$releasever/AppStream/$basearch/os/ +gpgcheck=1 +enabled=1 +countme=1 +metadata_expire=6h +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9 diff --git a/elements/rocky-minimal-yum/README.rst b/elements/rocky-minimal-yum/README.rst new file mode 100644 index 0000000..2f9ce6b --- /dev/null +++ b/elements/rocky-minimal-yum/README.rst @@ -0,0 +1,29 @@ +=========== +yum-minimal +=========== +Base element for creating minimal yum-based images. + +This element is incomplete by itself, you'll want to use the centos-minimal +or fedora-minimal elements to get an actual base image. + +Use of this element will require 'yum' and 'yum-utils' to be installed on +Ubuntu and Debian. Nothing additional is needed on Fedora or CentOS. + +If you wish to have DHCP networking setup for eth0 & eth1 via +/etc/sysconfig/network-config scripts/ifcfg-eth[0|1], set the +environment variable `DIB_YUM_MINIMAL_CREATE_INTERFACES` to `1`. + +If you wish to build from specific mirrors, set +``DIB_YUM_MINIMAL_BOOTSTRAP_REPOS`` to a directory with the ``.repo`` +files to use during bootstrap and build. The repo files should be +named with a prefix ``dib-mirror-`` and will be removed from the final +image. + +If you wish to include extra repositories, set ``DIB_YUM_MINIMAL_EXTRA_REPOS`` +to a directory with the ``.repo`` files. The repo files will not be removed +from the final image. + +If you are bootstrapping a custom or unsupported OS, and need to install +additional packages to setup the base chroot, set +``DIB_YUM_MINIMAL_BOOTSTRAP_PACKAGES`` to the list of additional packages to +install. diff --git a/elements/rocky-minimal-yum/cleanup.d/95-remove-yum-mirror b/elements/rocky-minimal-yum/cleanup.d/95-remove-yum-mirror new file mode 100755 index 0000000..343c16d --- /dev/null +++ b/elements/rocky-minimal-yum/cleanup.d/95-remove-yum-mirror @@ -0,0 +1,35 @@ +#!/bin/bash +# +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +# dib-lint: disable=safe_sudo + +if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +# This removes any build-time repos that might be set in 08-yum-chroot +if [[ -n ${DIB_YUM_MINIMAL_BOOTSTRAP_REPOS:-} ]]; then + + sudo rm -f $TMP_MOUNT_PATH/etc/yum.repos.d/dib-mirror*.repo + + for repo in $TMP_MOUNT_PATH/etc/yum.repos.d/*.USING_MIRROR; do + sudo mv $repo ${repo/.USING_MIRROR/} + done + +fi diff --git a/elements/rocky-minimal-yum/element-deps b/elements/rocky-minimal-yum/element-deps new file mode 100644 index 0000000..ba3a453 --- /dev/null +++ b/elements/rocky-minimal-yum/element-deps @@ -0,0 +1,3 @@ +redhat-common +rpm-distro +yum diff --git a/elements/rocky-minimal-yum/install.d/10-base-networking b/elements/rocky-minimal-yum/install.d/10-base-networking new file mode 100755 index 0000000..0072ab1 --- /dev/null +++ b/elements/rocky-minimal-yum/install.d/10-base-networking @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +# allow networking init scripts inside the container to work without extra steps +cat << EOF | sudo tee /etc/sysconfig/network > /dev/null +NETWORKING=yes +NETWORKING_IPV6=yes +NOZEROCONF=yes +EOF + +# If you want eth0 and eth1 created as DHCP based interfaces, enable +# this. You don't want this if systemd is going to call the +# interfaces on the real system something else, or if you're using a +# network-manager like cloud-init, glean or network-manager that will +# handle the interfaces dynamically. +if [[ "${DIB_YUM_MINIMAL_CREATE_INTERFACES:-0}" -eq "1" ]]; then + for interface in eth0 eth1; do + cat << EOF | tee /etc/sysconfig/network-scripts/ifcfg-$interface > /dev/null +DEVICE=$interface +BOOTPROTO=dhcp +ONBOOT=on +EOF + done +fi diff --git a/elements/rocky-minimal-yum/install.d/11-ensure-dbus-daemon b/elements/rocky-minimal-yum/install.d/11-ensure-dbus-daemon new file mode 100755 index 0000000..ae1534d --- /dev/null +++ b/elements/rocky-minimal-yum/install.d/11-ensure-dbus-daemon @@ -0,0 +1,28 @@ +#!/bin/bash +# +# Copyright 2019 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +# Ensure that dbus-daemon is enabled; fedora 30 and above has switched to +# dbus-broker. +if [[ ${DISTRO_NAME} == 'fedora' && ${DIB_RELEASE} -eq 29 ]]; then + systemctl --no-reload enable dbus-daemon.service +fi diff --git a/elements/rocky-minimal-yum/package-installs.yaml b/elements/rocky-minimal-yum/package-installs.yaml new file mode 100644 index 0000000..9c940fa --- /dev/null +++ b/elements/rocky-minimal-yum/package-installs.yaml @@ -0,0 +1,22 @@ +bash: +binutils: +coreutils-single: +crypto-policies-scripts: +curl-minimal: +findutils: +glibc-minimal-langpack: +gzip: +hostname: +less: +libcurl-minimal: +libusbx: +linux-firmware: + uninstall: true +linux-firmware-whence: + uninstall: true +lsb_release: +rootfiles: +tar: +usermode: +vim-minimal: +yum: diff --git a/elements/rocky-minimal-yum/pkg-map b/elements/rocky-minimal-yum/pkg-map new file mode 100644 index 0000000..b6c4f30 --- /dev/null +++ b/elements/rocky-minimal-yum/pkg-map @@ -0,0 +1,7 @@ +{ + "family": { + "redhat": { + "lsb_release": "ed hostname patch postfix tar time" + } + } +} diff --git a/elements/rocky-minimal-yum/pre-install.d/03-yum-cleanup b/elements/rocky-minimal-yum/pre-install.d/03-yum-cleanup new file mode 100755 index 0000000..e77e4bf --- /dev/null +++ b/elements/rocky-minimal-yum/pre-install.d/03-yum-cleanup @@ -0,0 +1,84 @@ +#!/bin/bash +# +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target" + +# This is only required on CentOS7 ... see notes in +# root.d/08-yum-chroot about %_install_langs +if [[ $DISTRO_NAME == "centos" && $DIB_RELEASE == "7" ]]; then + + # Stripping *all* locales is a bad idea. For now, we take the + # suggestion in [1] for reducing this + # [1] https://bugzilla.redhat.com/show_bug.cgi?id=156477 + + if [ ! -f /usr/lib/locale/locale-archive ]; then + die "locale-archive not found? Can not do cleanup." + fi + + # now the archive has everything in it, and is about 100MiB. Strip it + # to just en_US (basically, this is the locale we support if you ssh + # in, other than POSIX) + localedef --delete-from-archive \ + $(localedef --list-archive | grep -v '^en_US' | xargs) + + # This removes the locales from the archive index but doesn't rebuild + # the file, so it is still the same size (maybe it is sparse? + # presumably as it's mmapped you don't want to fiddle with the offsets + # of locales in the archive on a live system. We are not live). + + # build-locale-archive is a tool provided by the RH packaging of + # glibc. Documentation is scarce, but it takes the pre-built locales + # in the tmpl file and creates an archive. It seems originally the + # installer would set some flags to rpm to tell the package what + # languages to pick out of the template, but along the way, this was + # reverted to install them (size considered less important than locale + # support). + + # We hack this by moving the locale-archive we've removed the extra + # locales from to the template, then re-run the build. + mv /usr/lib/locale/locale-archive /usr/lib/locale/locale-archive.tmpl + + # rebuild archive from template + /usr/sbin/build-locale-archive + + # leave empty template behind as package does. I think this stops + # upgrades redoing things + echo > /usr/lib/locale/locale-archive.tmpl + + # remove the unnecessary source locale files and iconv files + pushd /usr/share/locale + find . ! -name 'locale.alias' -delete + popd + rm -rf {lib.lib64}/gconv + +fi + +# docs +rm -rf /usr/share/{doc,info,gnome/help} +# i18n +rm -rf /usr/share/i18n +# sln +rm -rf /sbin/sln +# ldconfig +rm -rf /etc/ld.so.cache /var/cache/ldconfig +mkdir -p --mode=0755 /var/cache/ldconfig diff --git a/elements/rocky-minimal-yum/root.d/08-yum-chroot b/elements/rocky-minimal-yum/root.d/08-yum-chroot new file mode 100755 index 0000000..45efe7f --- /dev/null +++ b/elements/rocky-minimal-yum/root.d/08-yum-chroot @@ -0,0 +1,416 @@ +#!/bin/bash +# +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +# dib-lint: disable=safe_sudo + +if [ "${DIB_DEBUG_TRACE:-0}" -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +source $_LIB/common-functions + +if [ -f ${TARGET_ROOT}/.extra_settings ] ; then + . ${TARGET_ROOT}/.extra_settings +fi +ARCH=${ARCH:-x86_64} +if [ $ARCH = amd64 ]; then + ARCH=x86_64 +elif [[ "arm64" == "$ARCH" ]]; then + ARCH="aarch64" +fi +# Calling elements will need to set DISTRO_NAME and DIB_RELEASE +# TODO Maybe deal with DIB_DISTRIBUTION_MIRROR +http_proxy=${http_proxy:-} +YUM=${YUM:-yum} + +WORKING=$(mktemp --tmpdir=${TMP_DIR:-/tmp} -d) +EACTION="rm -r $WORKING" +trap "$EACTION" EXIT + +YUM_CACHE=$DIB_IMAGE_CACHE/yum +mkdir -p $YUM_CACHE + +# Debian Bullseye and beyond only has DNF locally +HOST_YUM_DOWNLOADER="yumdownloader" +HOST_YUM="yum" +if ! command -v yumdownloader &> /dev/null +then + HOST_YUM_DOWNLOADER="dnf download" + HOST_YUM="dnf" +fi + + +# Note, on Debian/Ubuntu, %_dbpath is set in the RPM macros as +# ${HOME}/.rpmdb/ -- this makes sense as RPM isn't the system +# packager. This path is relative to the "--root" argument +_RPM="rpm --dbpath=/var/lib/rpm" + +# install the [fedora|centos]-[release|repo] packages inside the +# chroot, which are needed to bootstrap yum/dnf +# +# note this runs outside the chroot, where we're assuming the platform +# has yum/yumdownloader/dnf download +function _install_repos { + local packages + local rc + + # pre-install the base system packages via rpm. We previously + # just left it up to yum to drag these in when we "yum install + # yum" in the chroot in _install_pkg_manager. This raised a small + # problem that inside the empty chroot yum went ahead and did a + # mkdir for /var/run to put some pid file in, which then messed up + # the "filesystem" package making /var/run a symlink to /run + # ... which leads to odd issues with a running system. + # + # TODO: these packages still have some small %posttrans stuff that + # depends on other packages (see rhbz#1306489) ... maybe the idea + # is that they are only installed in one big transaction with the + # rest of the system? but we don't want to use yum to do this + # (see above) so ... + packages="${DIB_YUM_MINIMAL_BOOTSTRAP_PACKAGES:-} " + packages+="basesystem filesystem setup " + if [[ ${DISTRO_NAME} = fedora ]]; then + packages+="fedora-release-cloud fedora-release-common " + packages+="fedora-repos fedora-gpg-keys" + elif [[ ${DISTRO_NAME} = rocky ]]; then + packages+="rocky-release rocky-repos rocky-gpg-keys" + elif [[ ${DISTRO_NAME} = centos && ${DIB_RELEASE%-stream} -gt 7 ]]; then + packages+="centos-gpg-keys " + if [[ "$DIB_RELEASE" =~ (stream) ]]; then + packages+="centos-stream-release centos-stream-repos " + else + packages+="centos-linux-release centos-linux-repos " + fi + elif [[ ${DISTRO_NAME} == 'openeuler' ]]; then + packages+="openEuler-release " + packages+="openEuler-repos openEuler-gpg-keys " + else + # NOTE(ianw) 2022-04-20 : can probably remove when we don't + # support centos 7, unlikely anything else ends up here at + # this point. + packages+="${DISTRO_NAME}-release " + fi + + # By default, parent elements (fedora-minimal, centos-minimal) + # have a yum.repos.d directory in the element with a default repo; + # this is copied to TMP_HOOK_PATH by the usual hook-copying + # routines. In the gate, environment.d files for the funtional + # tests will set DIB_YUM_MINIMAL_BOOTSTRAP_REPOS -- this contains + # mirrors correct for the region setup by the + # dib-setup-gate-mirrors role. + local repo=${DIB_YUM_MINIMAL_BOOTSTRAP_REPOS:-} + if [[ -z ${repo} ]]; then + # take in preference more specific subdirs + if [[ -d ${TMP_HOOKS_PATH}/yum.repos.d/${DIB_RELEASE} ]]; then + repo=${TMP_HOOKS_PATH}/yum.repos.d/${DIB_RELEASE} + else + repo=${TMP_HOOKS_PATH}/yum.repos.d + fi + fi + + # yumdownloader puts repo xml files and such into a directory + # ${TMPDIR}/yum-$USER-random. Since we don't need this once the + # initial download happens, redirect TMPDIR for this call so we + # can clean it up nicely + # + # Note that the $releasever for centos-stream is just the major + # version. There is another variable "$stream" that we don't pass + local temp_tmp + temp_tmp=$(mktemp -d) + TMPDIR=${temp_tmp} ${HOST_YUM_DOWNLOADER} --verbose \ + --releasever=${DIB_RELEASE/-*/} \ + --setopt=reposdir=$repo \ + --setopt=cachedir=$temp_tmp \ + --destdir=$WORKING \ + ${packages} && rc=$? || rc=$? + rm -rf ${temp_tmp} + if [[ ${rc} != 0 ]]; then + die "Failed to download initial packages: ${packages}" + fi + + # --nodeps works around these wanting /bin/sh in some fedora + # releases, see rhbz#1265873 + sudo $_RPM --root $TARGET_ROOT --nodeps -ivh $WORKING/*rpm + + # install the bootstrap mirror repos over the default ones, if + # set. we will remove this at the end so the final image has + # regular mirrors + if [[ -n ${DIB_YUM_MINIMAL_BOOTSTRAP_REPOS:-} ]]; then + for repo in $TARGET_ROOT/etc/yum.repos.d/*.repo; do + sudo mv $repo $repo.USING_MIRROR + done + sudo cp ${DIB_YUM_MINIMAL_BOOTSTRAP_REPOS}/* \ + $TARGET_ROOT/etc/yum.repos.d/ + fi + + if [[ -n ${DIB_YUM_MINIMAL_EXTRA_REPOS:-} ]]; then + sudo cp ${DIB_YUM_MINIMAL_EXTRA_REPOS}/* \ + $TARGET_ROOT/etc/yum.repos.d/ + fi + + # For openEuler, some repos like update are disabled by default. + # Ensure all the repo is enabled, so that we get the latest packages. + if [[ ${DISTRO_NAME} == 'openeuler' ]]; then + sudo sed -i 's/enabled=0/enabled=1/' $TARGET_ROOT/etc/yum.repos.d/*.repo + fi + + +} + +# _install_pkg_manager packages... +# +# install the package manager packages. This is done outside the chroot +# and with yum from the build system. +# TODO: one day build systems will be dnf only, but we don't handle +# that right now +function _install_pkg_manager { + # Install into the chroot, using the gpg keys from the release + # rpm's installed in the chroot + sudo sed -i "s,/etc/pki/rpm-gpg,$TARGET_ROOT/etc/pki/rpm-gpg,g" \ + $TARGET_ROOT/etc/yum.repos.d/*repo + + # See notes on $_RPM variable -- we need to override the + # $HOME-based dbpath set on debian/ubuntu here. Unfortunately, + # yum does not have a way to override rpm macros from the command + # line. So we modify the user's ~/.rpmmacros to set %_dbpath back + # to "/var/lib/rpm" (note, this is taken relative to the + # --installroot). + # + # Also note, we only want this done around this call -- this is + # the only place we are using yum outside the chroot, and hence + # picking up the base-system's default rpm macros. For example, + # the yumdownloader calls above in _install_repos want to use + # ~/.rpmdb/ ... there is nothing in the build-system /var/lib/rpm! + # + # Another issue we hit is having to set --releasever here. yum + # determines $releasever based on (more or less) "rpm -q + # --whatprovides $distroverpkg". By default, this is + # "redhat-release" (fedora-release provides redhat-release) but + # some platforms like CentOS override it in /etc/yum.conf (to + # centos-release in their case). You can't override this (see + # [1]), but setting --releasever works around this. + # + # [1] https://bugzilla.redhat.com/show_bug.cgi?id=1287333 + ( + flock -w 1200 9 || die "Can not lock .rpmmacros" + echo "%_dbpath /var/lib/rpm" >> $HOME/.rpmmacros + + local _lang_pack="" + local _extra_pkgs="" + + if [[ $DISTRO_NAME == "fedora" ]] || \ + [[ $DISTRO_NAME == "centos" && $DIB_RELEASE > "7" ]] || \ + [[ $DISTRO_NAME == 'rocky' ]]; then + # glibc from F24 onwards has split locales into "langpack" + # packages. Host yum doesn't understand the + # weak-dependencies glibc now uses to get the + # minimal-langpack and chooses a random(ish) one that + # satisfies the locale dependency (rhbz#1349258). + # Work-around this by explicitly requring the minimal and + # english (for en_US.UTF-8) pack. + _lang_pack="glibc-minimal-langpack glibc-langpack-en" + fi + + # Yum has some issues choosing weak dependencies. It can end + # up choosing "coreutils-single" instead of "coreutils" which + # causes problems later when a package actually requires + # coreutils. For more info see + # https://bugzilla.redhat.com/show_bug.cgi?id=1286445 + # Really all we can do is pre-install the right thing + _extra_pkgs+="coreutils-single " + + # Legacy yum reads vars from directory /etc/yum/vars and, unlike dnf, + # does not provide setopt=varsdir. So, if $YUM is legacy yum and our + # target root is dnf, symlink dnf vars. + if [[ ! -d $TARGET_ROOT/etc/yum/vars ]]; then + sudo mkdir -p $TARGET_ROOT/etc/yum + sudo ln -s $TARGET_ROOT/etc/dnf/vars $TARGET_ROOT/etc/yum/vars + fi + + if [[ ${DISTRO_NAME} == 'rocky' ]]; then + echo 'stg/rocky' | sudo tee /etc/dnf/vars/contentdir + fi + + sudo -E ${HOST_YUM} -y \ + --disableexcludes=all \ + --setopt=cachedir=$YUM_CACHE/$ARCH/$DIB_RELEASE \ + --setopt=reposdir=$TARGET_ROOT/etc/yum.repos.d \ + --releasever=${DIB_RELEASE/-*/} \ + --installroot $TARGET_ROOT \ + install $@ ${_lang_pack} ${_extra_pkgs} && rc=$? || rc=$? + + # we may have symlinked yum/vars -> dnf/vars, unset if so + sudo unset $TARGET_ROOT/etc/yum/vars 2>/dev/null || true + + # Note we've modified the base system's .rpmmacros. Ensure we + # clean it up *always* + # sed makes it easy to remove last line, but not last n lines... + sed -i '$ d' $HOME/.rpmmacros; sed -i '$ d' $HOME/.rpmmacros; + if [ $rc != 0 ]; then + die "Initial yum install to chroot failed! Can not continue." + fi + ) 9>$DIB_LOCKFILES/.rpmmacros.dib.lock + + # Set gpg path back because subsequent actions will take place in + # the chroot + sudo sed -i "s,$TARGET_ROOT/etc/pki/rpm-gpg,/etc/pki/rpm-gpg,g" \ + $TARGET_ROOT/etc/yum.repos.d/*repo +} + +# Note this is not usually done for root.d elements (see +# lib/common-functions:mount_proc_dev_sys) but it's important that +# we have things like /dev/urandom around inside the chroot for +# the rpm [pre|post]inst scripts within the packages. +sudo mkdir -p $TARGET_ROOT/proc $TARGET_ROOT/dev $TARGET_ROOT/sys +sudo mount -t proc none $TARGET_ROOT/proc +sudo mount --bind /dev $TARGET_ROOT/dev +sudo mount -t devpts $(mount_dev_pts_options) devpts $TARGET_ROOT/dev/pts +# Mounting /sys as RO indicates to various systemd things +# that we are in a container +sudo mount -o ro -t sysfs none $TARGET_ROOT/sys + +# initalize rpmdb +sudo mkdir -p $TARGET_ROOT/var/lib/rpm +sudo $_RPM --root $TARGET_ROOT --initdb + +# this makes sure that running yum/dnf in the chroot it can get +# out to download stuff +sudo mkdir $TARGET_ROOT/etc +sudo cp /etc/resolv.conf $TARGET_ROOT/etc/resolv.conf + +# Bind mount the external yum cache inside the chroot. Same logic +# as in the yum element to provide for yum caching copied here +# because the sequencing is wrong otherwise +sudo mkdir -p $TMP_MOUNT_PATH/tmp/yum +sudo mount --bind $YUM_CACHE $TMP_MOUNT_PATH/tmp/yum + +_install_repos + +# Install package manager + +# We are somewhat fighting against the "yum" version on the host to +# get things installed correctly. Fedora 27 onwards has a +# "curl-minimal" package that will get pulled in by default for the +# initial install (ianw: I think because the yum doesn't understand +# weak dependencies correctly). This causes problems later if/when +# "curl" gets installed (you need to add --allowerasing to let dnf get +# rid of the old package). To avoid this, just install the full curl +# and first up. On Centos, it's different again and we need to +# specify libcurl as well, or the minimal libcurl packages come in +# causing similar problems. *But* -- we can't also do that on Fedora +# it seems, as it seems like as part of the Fedora modular updates +# (https://docs.fedoraproject.org/en-US/modularity/) we can pick up +# seemingly mismatched libraries. +if [[ ${DISTRO_NAME} =~ (fedora|openeuler|rocky) ]]; then + _install_pkg_manager dnf dnf-plugins-core curl-minimal libcurl-minimal +elif [[ ${DISTRO_NAME} == centos && $DIB_RELEASE > "7" ]]; then + _install_pkg_manager dnf dnf-plugins-core curl libcurl +else + _install_pkg_manager yum +fi + +# sort of like run_in_target; but we're not in a phase where that +# works yet. strip unnecessary external env vars that can cause +# problems. +function _run_chroot { + local cmd="$@" + sudo -E chroot $TARGET_ROOT env -u TMPDIR sh -c "$cmd" +} + +# The rpmdb has been created by the host RPM. CentOS 7 only +# understands bdb-based db's, while the host is (likey as not) a more +# modern rpm that has created a sqlite db. These don't share files in +# common, so to the in-chroot rpm the db just looks empty. This is a +# super-weird state that the system is in, because everything is +# installed and working, but packages don't look like they are. One +# consequence of this is that yum's querying to setup the $releasever +# variable fails and it remains unset. Because the default .repo +# files use this we get invalid repo paths for any yum commands. The +# easiest way around this seems to be to manually set --releasever=7; +# this way yum can rebuild itself and recreate the rpmdb as it likes. +# This is a mess that can hopefully go away when we don't care about +# CentOS 7. For this reason, we only do this for CentOS 7, to avoid +# hiding any problems on other distros. We only need to do this +# for these initial steps, after that the db is correct. +if [[ ${DISTRO_NAME} = centos && ${DIB_RELEASE%-stream} -le 7 ]]; then + YUM="${YUM} --releasever=${DIB_RELEASE}" +fi + +if [[ ${DISTRO_NAME} == 'rocky' ]]; then + YUM="DNF_VAR_contentdir=stg/rocky ${YUM}" +fi + +# we just installed yum/dnf with "outside" tools (yum/rpm) which +# might have created /var/lib/[yum|rpm] (etc) that are slighlty +# incompatible. Refresh everything with the in-chroot tools +_run_chroot rpm --rebuilddb +_run_chroot ${YUM} clean all + +# populate the lang reduction macro in the chroot +echo "%_install_langs C:en_US:en_US.UTF-8" | \ + sudo tee -a $TARGET_ROOT/etc/rpm/macros.langs > /dev/null + +_base_packages="systemd passwd findutils sudo util-linux-ng " + +# This package is split out from systemd on >F24, dracut is +# missing the dependency and will fail to make an initrd without +# it; see +# https://bugzilla.redhat.com/show_bug.cgi?id=1398505 +_base_packages+="systemd-udev " + +# bootstrap the environment within the chroot; bring in new +# metadata with an update and install some base packages we need. +_run_chroot ${YUM} -y update +_run_chroot ${YUM} -y \ + --setopt=cachedir=/tmp/yum/$ARCH/$DIB_RELEASE \ + install ${_base_packages} + +# Put in a dummy /etc/resolv.conf over the temporary one we used +# to bootstrap. systemd has a bug/feature [1] that it will assume +# you want systemd-networkd as the network manager and create a +# broken symlink to /run/... if the base image doesn't have one. +# This broken link confuses things like dhclient. +# [1] https://bugzilla.redhat.com/show_bug.cgi?id=1197204 +echo -e "# This file intentionally left blank\n" | \ + sudo tee $TARGET_ROOT/etc/resolv.conf + +# set the most reliable UTF-8 locale +echo -e 'LANG="en_US.UTF-8"' | \ + sudo tee $TARGET_ROOT/etc/locale.conf + # default to UTC +_run_chroot ln -sf /usr/share/zoneinfo/UTC \ + /etc/localtime + +# cleanup +# TODO : move this into a exit trap; and reconsider how +# this integrates with the global exit cleanup path. +sudo umount $TMP_MOUNT_PATH/tmp/yum +sudo umount $TARGET_ROOT/proc +sudo umount $TARGET_ROOT/dev/pts +sudo umount $TARGET_ROOT/dev +sudo umount $TARGET_ROOT/sys + +# RPM doesn't know whether files have been changed since install +# At this point though, we know for certain that we have changed no +# config files, so anything marked .rpmnew is just a bug. +for newfile in $(sudo find $TARGET_ROOT -type f -name '*rpmnew') ; do + sudo mv $newfile $(echo $newfile | sed 's/.rpmnew$//') +done + +sudo rm -f ${TARGET_ROOT}/.extra_settings