From d56da2bc4b3fc69c037d67629c7f830eb357656f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2024 16:04:55 +0200 Subject: [PATCH 1/5] dnf, yum: set global options before command The `-y` and `-q` options are global options, and can be set before the command that's run. There's some ambiguity in the USAGE output of different versions (`yum`, `dnf`, `dnf5`) yum always outputs the same usage, but shows that options go _before_ the command; yum --help Usage: yum [options] COMMAND yum install --help Usage: yum [options] COMMAND dnf (dnf4) is ambiguous; when showing usage for `install` it shows the options to be set _after_ the command; dnf install --help usage: dnf install [-c [config file]] [-q] [-v] [--version] .... but the global `--help` shows them to be before the command; dnf --help usage: dnf [options] COMMAND General DNF options: ... -q, --quiet quiet operation -v, --verbose verbose operation ,,, --setopt SETOPTS set arbitrary config and repo options dnf5 is more explicit about global vs per-command options; dnf --help Usage: dnf5 [GLOBAL OPTIONS] ... dnf install --help Usage: dnf5 [GLOBAL OPTIONS] install [OPTIONS] [ARGUMENTS] Testing shows that older versions (`dnf4` and `yum`) handle both fine, and because `dnf5` (per the above) prefers global options to go before the command, we can use that convention in this script. Signed-off-by: Sebastiaan van Stijn --- install.sh | 8 ++++---- rootless-install.sh | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/install.sh b/install.sh index 3a0a94d4..2fd98f70 100755 --- a/install.sh +++ b/install.sh @@ -554,14 +554,14 @@ do_install() { centos|fedora|rhel) if command_exists dnf; then pkg_manager="dnf" - pkg_manager_flags="--best" + pkg_manager_flags="-y -q --best" config_manager="dnf config-manager" enable_channel_flag="--set-enabled" disable_channel_flag="--set-disabled" pre_reqs="dnf-plugins-core" else pkg_manager="yum" - pkg_manager_flags="" + pkg_manager_flags="-y -q" config_manager="yum-config-manager" enable_channel_flag="--enable" disable_channel_flag="--disable" @@ -578,7 +578,7 @@ do_install() { if ! is_dry_run; then set -x fi - $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pre_reqs" + $sh_c "$pkg_manager $pkg_manager_flags install $pre_reqs" $sh_c "$config_manager --add-repo $repo_file_url" if [ "$CHANNEL" != "stable" ]; then @@ -631,7 +631,7 @@ do_install() { if ! is_dry_run; then set -x fi - $sh_c "$pkg_manager $pkg_manager_flags install -y -q $pkgs" + $sh_c "$pkg_manager $pkg_manager_flags install $pkgs" ) echo_docker_as_nonroot exit 0 diff --git a/rootless-install.sh b/rootless-install.sh index cd080e22..797df61c 100755 --- a/rootless-install.sh +++ b/rootless-install.sh @@ -130,10 +130,10 @@ checks() { if command -v apt-get >/dev/null 2>&1; then INSTRUCTIONS="apt-get install -y uidmap" elif command -v dnf >/dev/null 2>&1; then - INSTRUCTIONS="dnf install -y shadow-utils" + INSTRUCTIONS="dnf -y install shadow-utils" elif command -v yum >/dev/null 2>&1; then INSTRUCTIONS="curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo -yum install -y shadow-utils46-newxidmap" +yum -y install shadow-utils46-newxidmap" else echo "newuidmap binary not found. Please install with a package manager." exit 1 @@ -147,7 +147,7 @@ yum install -y shadow-utils46-newxidmap" apt-get install -y iptables" elif command -v dnf >/dev/null 2>&1; then INSTRUCTIONS="${INSTRUCTIONS} -dnf install -y iptables" +dnf -y install iptables" else echo "iptables binary not found. Please install with a package manager." exit 1 From 4e6553081c2ed126ebf2db0b53e5d7ae43487fc9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2024 16:12:23 +0200 Subject: [PATCH 2/5] apt-get: set global options before command The `-y` and `-q` options are global options, and can be set before the command that's run; apt-get --help ... Usage: apt-get [options] command apt-get [options] install|remove pkg1 [pkg2 ...] apt-get [options] source pkg1 [pkg2 ...] Signed-off-by: Sebastiaan van Stijn --- install.sh | 8 ++++---- rootless-install.sh | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/install.sh b/install.sh index 2fd98f70..1f9f506e 100755 --- a/install.sh +++ b/install.sh @@ -498,13 +498,13 @@ do_install() { if ! is_dry_run; then set -x fi - $sh_c 'apt-get update -qq >/dev/null' - $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pre_reqs >/dev/null" + $sh_c 'apt-get -qq update >/dev/null' + $sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pre_reqs >/dev/null" $sh_c 'install -m 0755 -d /etc/apt/keyrings' $sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc" $sh_c "chmod a+r /etc/apt/keyrings/docker.asc" $sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list" - $sh_c 'apt-get update -qq >/dev/null' + $sh_c 'apt-get -qq update >/dev/null' ) pkg_version="" if [ -n "$VERSION" ]; then @@ -546,7 +546,7 @@ do_install() { if ! is_dry_run; then set -x fi - $sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y -qq $pkgs >/dev/null" + $sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pkgs >/dev/null" ) echo_docker_as_nonroot exit 0 diff --git a/rootless-install.sh b/rootless-install.sh index 797df61c..08dae10a 100755 --- a/rootless-install.sh +++ b/rootless-install.sh @@ -128,7 +128,7 @@ checks() { # uidmap dependency check if ! command -v newuidmap >/dev/null 2>&1; then if command -v apt-get >/dev/null 2>&1; then - INSTRUCTIONS="apt-get install -y uidmap" + INSTRUCTIONS="apt-get -y install uidmap" elif command -v dnf >/dev/null 2>&1; then INSTRUCTIONS="dnf -y install shadow-utils" elif command -v yum >/dev/null 2>&1; then @@ -144,7 +144,7 @@ yum -y install shadow-utils46-newxidmap" if [ -z "$SKIP_IPTABLES" ] && ! command -v iptables >/dev/null 2>&1 && [ ! -f /sbin/iptables ] && [ ! -f /usr/sbin/iptables ]; then if command -v apt-get >/dev/null 2>&1; then INSTRUCTIONS="${INSTRUCTIONS} -apt-get install -y iptables" +apt-get -y install iptables" elif command -v dnf >/dev/null 2>&1; then INSTRUCTIONS="${INSTRUCTIONS} dnf -y install iptables" From b9824740ec430eb2ac19963cb53d54778cf542d7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2024 16:24:26 +0200 Subject: [PATCH 3/5] add support for dnf5 Fedora 41 and up use the new dnf5 as default, which is a rewrite of the dnf commands with different options; + dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo Unknown argument "--add-repo" for command "config-manager". Add "--help" for more information about the arguments. make: *** [Makefile:95: verify] Error 2 script returned exit code 2 This patch: - adds a check for dnf5 - removes some indirection through env-vars, and instead inlines the code Note that with CentOS 7 being EOL, we can probably remove the `yum` variant from the script, but I left those in place for now. Signed-off-by: Sebastiaan van Stijn --- install.sh | 65 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/install.sh b/install.sh index 1f9f506e..4229ea9b 100755 --- a/install.sh +++ b/install.sh @@ -552,46 +552,57 @@ do_install() { exit 0 ;; centos|fedora|rhel) - if command_exists dnf; then - pkg_manager="dnf" - pkg_manager_flags="-y -q --best" - config_manager="dnf config-manager" - enable_channel_flag="--set-enabled" - disable_channel_flag="--set-disabled" - pre_reqs="dnf-plugins-core" - else - pkg_manager="yum" - pkg_manager_flags="-y -q" - config_manager="yum-config-manager" - enable_channel_flag="--enable" - disable_channel_flag="--disable" - pre_reqs="yum-utils" - fi - - if [ "$lsb_dist" = "fedora" ]; then - pkg_suffix="fc$dist_version" - else - pkg_suffix="el" - fi repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE" ( if ! is_dry_run; then set -x fi - $sh_c "$pkg_manager $pkg_manager_flags install $pre_reqs" - $sh_c "$config_manager --add-repo $repo_file_url" + if command_exists dnf5; then + $sh_c "dnf -y -q install dnf-plugins-core" + $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --from-repofile='$repo_file_url'" + + if [ "$CHANNEL" != "stable" ]; then + $sh_c "dnf5 config-manager setopt 'docker-ce-*.enabled=0'" + $sh_c "dnf5 config-manager setopt 'docker-ce-$CHANNEL.enabled=1'" + fi + $sh_c "dnf makecache" + elif command_exists dnf; then + $sh_c "dnf -y -q install dnf-plugins-core" + $sh_c "dnf config-manager --add-repo $repo_file_url" + + if [ "$CHANNEL" != "stable" ]; then + $sh_c "dnf config-manager --set-disabled 'docker-ce-*'" + $sh_c "dnf config-manager --set-enabled 'docker-ce-$CHANNEL'" + fi + $sh_c "dnf makecache" + else + $sh_c "yum -y -q install yum-utils" + $sh_c "yum config-manager --add-repo $repo_file_url" - if [ "$CHANNEL" != "stable" ]; then - $sh_c "$config_manager $disable_channel_flag 'docker-ce-*'" - $sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'" + if [ "$CHANNEL" != "stable" ]; then + $sh_c "yum config-manager --disable 'docker-ce-*'" + $sh_c "yum config-manager --enable 'docker-ce-$CHANNEL'" + fi + $sh_c "yum makecache" fi - $sh_c "$pkg_manager makecache" ) pkg_version="" + if command_exists dnf; then + pkg_manager="dnf" + pkg_manager_flags="-y -q --best" + else + pkg_manager="yum" + pkg_manager_flags="-y -q" + fi if [ -n "$VERSION" ]; then if is_dry_run; then echo "# WARNING: VERSION pinning is not supported in DRY_RUN" else + if [ "$lsb_dist" = "fedora" ]; then + pkg_suffix="fc$dist_version" + else + pkg_suffix="el" + fi pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix" search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'" pkg_version="$($sh_c "$search_command")" From 5cf619df82906bc7017b7233f46df73b014647c2 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2024 16:47:17 +0200 Subject: [PATCH 4/5] don't install weak-dependencies for dnf-core-utils We only need the config-manager, but it comes with a large number of weak dependencies; dnf -q install dnf-plugins-core Transaction Summary: Installing: 78 packages Disable weak dependencies to skip those, as they're not essential for this script; dnf -q --setopt=install_weak_deps=False install dnf-plugins-core Transaction Summary: Installing: 32 packages Signed-off-by: Sebastiaan van Stijn --- install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index 4229ea9b..e585c3be 100755 --- a/install.sh +++ b/install.sh @@ -558,7 +558,7 @@ do_install() { set -x fi if command_exists dnf5; then - $sh_c "dnf -y -q install dnf-plugins-core" + $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --from-repofile='$repo_file_url'" if [ "$CHANNEL" != "stable" ]; then @@ -567,7 +567,7 @@ do_install() { fi $sh_c "dnf makecache" elif command_exists dnf; then - $sh_c "dnf -y -q install dnf-plugins-core" + $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" $sh_c "dnf config-manager --add-repo $repo_file_url" if [ "$CHANNEL" != "stable" ]; then From 27f47c592a72999298581970a9d9339c14e842ba Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2024 16:49:56 +0200 Subject: [PATCH 5/5] add workaround for dnf5 addrepo bug The addrepo command has a bug that causes it to fail if the `.repo` file contains empty lines, causing it to fail; dnf config-manager addrepo --from-repofile="https://download.docker.com/linux/fedora/docker-ce.repo" Error in added repository configuration file. Cannot set repository option "#1= ": Option "#1" not found Use a temporary file and strip empty lines as a workaround until the bug is fixed. Signed-off-by: Sebastiaan van Stijn --- install.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/install.sh b/install.sh index e585c3be..ff6c2a50 100755 --- a/install.sh +++ b/install.sh @@ -558,8 +558,15 @@ do_install() { set -x fi if command_exists dnf5; then - $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" - $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --from-repofile='$repo_file_url'" + # $sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core" + # $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --from-repofile='$repo_file_url'" + + $sh_c "dnf -y -q --setopt=install_weak_deps=False install curl dnf-plugins-core" + # FIXME(thaJeztah); strip empty lines as workaround for https://github.com/rpm-software-management/dnf5/issues/1603 + TMP_REPO_FILE="$(mktemp --dry-run)" + $sh_c "curl -fsSL '$repo_file_url' | tr -s '\n' > '${TMP_REPO_FILE}'" + $sh_c "dnf5 config-manager addrepo --save-filename=docker-ce.repo --overwrite --from-repofile='${TMP_REPO_FILE}'" + $sh_c "rm -f '${TMP_REPO_FILE}'" if [ "$CHANNEL" != "stable" ]; then $sh_c "dnf5 config-manager setopt 'docker-ce-*.enabled=0'"