Skip to content

Commit c5dc231

Browse files
authored
Support podman (#2584)
1 parent e9cbfd6 commit c5dc231

51 files changed

Lines changed: 353 additions & 224 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-ethd.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ jobs:
3838
uses: douglascamata/setup-docker-macos-action@d5ccc6aae0ce23e7700154f5e63cc53e6433ac48
3939
- name: Prerequisites on Ubuntu
4040
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
41-
run: sudo apt-get install -y expect whiptail
41+
run: |
42+
sudo apt-get install -y expect whiptail
43+
sudo apt-get remove -y podman
4244
- name: Prerequisites on macOS
4345
if: ${{ startsWith(matrix.os, 'macos-') }}
4446
run: brew install bash newt coreutils expect gawk

anchor.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
x-logging: &logging
22
logging:
3-
driver: json-file
3+
driver: ${LOG_DRIVER}
44
options:
5-
max-size: 100m
6-
max-file: "3"
7-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
5+
max-size: ${LOG_MAX_SIZE}
6+
max-file: ${LOG_MAX_FILE}
7+
tag: ${LOG_TAG}
88

99
services:
1010
anchor:

besu.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
x-logging: &logging
22
logging:
3-
driver: json-file
3+
driver: ${LOG_DRIVER}
44
options:
5-
max-size: 100m
6-
max-file: "3"
7-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
5+
max-size: ${LOG_MAX_SIZE}
6+
max-file: ${LOG_MAX_FILE}
7+
tag: ${LOG_TAG}
88

99
services:
1010
execution:

central-metrics.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# For scraping with central-proxy-docker, when all you want is the metrics exporter
22
x-logging: &logging
33
logging:
4-
driver: json-file
4+
driver: ${LOG_DRIVER}
55
options:
6-
max-size: 100m
7-
max-file: "3"
8-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
6+
max-size: ${LOG_MAX_SIZE}
7+
max-file: ${LOG_MAX_FILE}
8+
tag: ${LOG_TAG}
99

1010
services:
1111
ethereum-metrics-exporter:

commit-boost-pbs.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
x-logging: &logging
22
logging:
3-
driver: json-file
3+
driver: ${LOG_DRIVER}
44
options:
5-
max-size: 100m
6-
max-file: "3"
7-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
5+
max-size: ${LOG_MAX_SIZE}
6+
max-file: ${LOG_MAX_FILE}
7+
tag: ${LOG_TAG}
88

99
services:
1010
cb-pbs:

contributoor.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
## Read more: https://github.com/ethpandaops/contributoor
33
x-logging: &logging
44
logging:
5-
driver: json-file
5+
driver: ${LOG_DRIVER}
66
options:
7-
max-size: 100m
8-
max-file: "3"
9-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
7+
max-size: ${LOG_MAX_SIZE}
8+
max-file: ${LOG_MAX_FILE}
9+
tag: ${LOG_TAG}
1010

1111
services:
1212
contributoor:

default.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@ ERE_URL=
289289

290290
# If you want debug logs, set this to debug instead of info
291291
LOG_LEVEL=info
292+
# Log retention and tagging
293+
LOG_DRIVER=json-file
294+
LOG_MAX_SIZE=100m
295+
LOG_MAX_FILE=3
296+
LOG_TAG='{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
292297

293298
# JWT secret for CL:EL connection. This is created automatically by default.
294299
# If specified manually here, this could be used to split CL and EL to different

erigon.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
x-logging: &logging
22
logging:
3-
driver: json-file
3+
driver: ${LOG_DRIVER}
44
options:
5-
max-size: 100m
6-
max-file: "3"
7-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
5+
max-size: ${LOG_MAX_SIZE}
6+
max-file: ${LOG_MAX_FILE}
7+
tag: ${LOG_TAG}
88

99
services:
1010
execution:

ethd

Lines changed: 132 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -143,30 +143,74 @@ __handle_docker() {
143143
local exitstatus
144144
local var
145145
local regex
146+
local message
147+
local use_podman=0
148+
local use_docker=0
146149

147150
if [[ "${__distro}" =~ (debian|ubuntu) ]]; then
148151
set +e
149-
if ! ${__docker_exe} images >/dev/null 2>&1; then
150-
if [[ "${__cannot_sudo}" -eq 1 ]]; then
151-
echo "Cannot call Docker and cannot use sudo. Please make your user part of the docker group"
152-
exit 1
152+
if dpkg-query -W -f='${Status}' docker-ce 2>/dev/null | grep -q "ok installed" \
153+
|| dpkg-query -W -f='${Status}' docker.io 2>/dev/null | grep -q "ok installed"; then
154+
use_docker=1
155+
fi
156+
if dpkg-query -W -f='${Status}' podman 2>/dev/null | grep -q "ok installed"; then
157+
use_podman=1
158+
fi
159+
160+
# If both are installed:
161+
# If DOCKER_SOCK is set to podman.sock, assume the user prefers podman
162+
# If service podman.socket is running, assume the user prefers podman
163+
# Otherwise, default to Docker
164+
if [[ "${use_docker}" -eq 1 && "${use_podman}" -eq 1 ]]; then
165+
echo "Both Docker and Podman are installed"
166+
echo "Guessing at user preference by \"DOCKER_SOCK\" in \".env\" and status of service podman.socket"
167+
var=DOCKER_SOCK
168+
__get_value_from_env "${var}" "${__env_file}" "__value"
169+
if [[ "${__value}" =~ podman.sock ]] || systemctl --user status podman.socket >/dev/null 2>&1 || systemctl status podman.socket >/dev/null 2>&1; then
170+
echo "Preferring Podman"
171+
echo
172+
use_docker=0
173+
else
174+
echo "Preferring Docker"
175+
echo
176+
use_podman=0
153177
fi
154-
echo "Will use sudo to access Docker"
155-
__docker_sudo="sudo"
156178
fi
157179

158-
if __dodocker system info --format '{{json .SecurityOptions}}' | grep -qi rootless; then
159-
systemctl --user status docker >/dev/null 2>&1
160-
exitstatus=$?
161-
message="\"systemctl --user status docker\" and \"journalctl --user -fu docker\" will be helpful."
180+
if [[ "${use_docker}" -eq 1 ]]; then
181+
if ${__docker_exe} system info --format '{{json .SecurityOptions}}' | grep -qi rootless; then
182+
systemctl --user status docker >/dev/null 2>&1
183+
exitstatus=$?
184+
message="\"systemctl --user status docker\" and \"journalctl --user -fu docker\" will be helpful."
185+
else
186+
systemctl status docker >/dev/null 2>&1
187+
exitstatus=$?
188+
message="\"systemctl status docker\" and \"sudo journalctl -fu docker\" will be helpful."
189+
fi
190+
if [[ ! "${exitstatus}" -eq 0 ]]; then
191+
echo "The Docker daemon is not running. Please check Docker installation."
192+
echo "${message}"
193+
echo "Aborting."
194+
exit 1
195+
fi
196+
elif [[ "${use_podman}" -eq 1 ]]; then
197+
__docker_exe=podman
198+
__compose_exe="podman compose"
199+
if systemctl status podman.socket >/dev/null 2>&1; then # User has enabled system socket, run podman with sudo.
200+
__docker_sudo="sudo"
201+
else
202+
systemctl --user status podman.socket >/dev/null 2>&1
203+
exitstatus=$?
204+
if [[ ! "${exitstatus}" -eq 0 ]]; then
205+
echo "The Podman socket service is not running. Please check Podman installation."
206+
echo "\"systemctl --user status podman.socket\" and \"journalctl --user -fu podman.socket\" will be helpful."
207+
echo "Aborting."
208+
exit 1
209+
fi
210+
fi
162211
else
163-
systemctl status docker >/dev/null 2>&1
164-
exitstatus=$?
165-
message="\"systemctl status docker\" and \"sudo journalctl -fu docker\" will be helpful."
166-
fi
167-
if [[ ! "${exitstatus}" -eq 0 ]]; then
168-
echo "The Docker daemon is not running. Please check Docker installation."
169-
echo "${message}"
212+
echo "Neither docker-ce, docker.io nor podman appear to be installed."
213+
echo "One of those is required to run ${__project_name}."
170214
echo "Aborting."
171215
exit 1
172216
fi
@@ -177,14 +221,24 @@ __handle_docker() {
177221
echo "The docker daemon is running. A non-packaged install is highly unusual and hard to maintain."
178222
echo "Please switch to docker-ce installed via the official Docker repo."
179223
fi
180-
else
181-
if ! ${__docker_exe} images >/dev/null 2>&1; then
182-
if [[ "${__cannot_sudo}" -eq 1 ]]; then
183-
echo "Cannot call Docker and cannot use sudo. Please make your user part of the docker group"
184-
exit 1
224+
if [[ -f "${__env_file}" ]]; then
225+
if [[ "${use_docker}" -eq 1 ]]; then
226+
LOG_DRIVER="json-file"
227+
LOG_TAG="'{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'"
228+
else
229+
LOG_DRIVER="journald"
230+
LOG_TAG="'{{.ImageName}}|{{.Name}}|{{.ID}}'"
231+
fi
232+
var=LOG_DRIVER
233+
__get_value_from_env "${var}" "${__env_file}" "__value"
234+
if [[ "${__value}" =~ ^(json-file|journald)$ ]]; then # Leave user overrides alone
235+
__update_value_in_env "${var}" "${!var}" "${__env_file}"
236+
fi
237+
var=LOG_TAG
238+
__get_value_from_env "${var}" "${__env_file}" "__value"
239+
if [[ "${__value}" =~ ^('{{\.ImageName}}\|{{\.Name}}\|{{\.ImageFullID}}\|{{\.FullID}}'|'{{\.ImageName}}\|{{\.Name}}\|{{\.ID}}')$ ]]; then # Leave user overrides alone
240+
__update_value_in_env "${var}" "${!var}" "${__env_file}"
185241
fi
186-
echo "Will use sudo to access Docker"
187-
__docker_sudo="sudo"
188242
fi
189243
fi
190244

@@ -193,7 +247,7 @@ __handle_docker() {
193247
__docker_minor_version=$(echo "${__docker_version}" | awk '{ split($1, version, "."); print version[2]; }')
194248
__docker_patch_version=$(echo "${__docker_version}" | awk '{ split($1, version, "."); print version[3]; }')
195249

196-
if [[ "${__docker_major_version}" -lt 23 ]]; then
250+
if [[ "${use_docker}" -eq 1 && "${__docker_major_version}" -lt 23 ]]; then
197251
# Debian 11 and Debian 12 have docker.io 20.10. From Debian 13, it's >= 26
198252
# Ubuntu has docker.io>= 27 from 22.04
199253
# The code to detect old docker.io can be removed when Debian 12 goes EOL in 2028
@@ -208,23 +262,47 @@ __handle_docker() {
208262
__oldish_docker=1
209263
fi
210264

265+
if ! ${__docker_sudo} ${__docker_exe} images >/dev/null 2>&1; then
266+
if [[ "${__cannot_sudo}" -eq 1 ]]; then
267+
echo "Cannot call ${__docker_exe} and cannot use sudo"
268+
if [[ "${__distro}" =~ (debian|ubuntu) && "${__docker_exe}" = "docker" ]]; then
269+
echo "Please make your user part of the docker group"
270+
fi
271+
exit 1
272+
fi
273+
echo "Will use sudo to access ${__docker_exe}"
274+
__docker_sudo="sudo"
275+
fi
276+
211277
if [[ -f "${__env_file}" && "${__distro}" =~ (debian|ubuntu) ]]; then
212-
DOCKER_ROOT=$(__dodocker system info --format '{{.DockerRootDir}}')
278+
if [[ "${__docker_exe}" = "podman" ]]; then
279+
DOCKER_ROOT=$(__dodocker system info --format '{{.Store.GraphRoot}}')
280+
else
281+
DOCKER_ROOT=$(__dodocker system info --format '{{.DockerRootDir}}')
282+
fi
213283
var=DOCKER_ROOT
214284
__get_value_from_env "${var}" "${__env_file}" "__value"
215285
if [[ "${DOCKER_ROOT}" != "${__value}" ]]; then
216286
__update_value_in_env "${var}" "${!var}" "${__env_file}"
217287
fi
218288

219289
# on macOS, user would set this manually to Colima or Docker Desktop value
220-
if __dodocker system info --format '{{.SecurityOptions}}' | grep -qi rootless; then
221-
DOCKER_SOCK=/run/user/$(id -u)/docker.sock
222-
if [[ "${__distro}" =~ (debian|ubuntu) && "${__docker_exe}" = "docker" && ( "${__docker_major_version}" -lt 29 \
223-
|| ( "${__docker_major_version}" -eq 29 && "${__docker_minor_version}" -lt 5 ) ) ]]; then
224-
__old_rootless_docker=1
290+
if [[ "${__docker_exe}" = "podman" ]]; then
291+
if [[ "$(__dodocker system info --format '{{.Host.Security.Rootless}}')" = "true" ]]; then
292+
DOCKER_SOCK=/run/user/$(id -u)/podman/podman.sock
293+
else
294+
DOCKER_SOCK=/run/podman/podman.sock
225295
fi
226296
else
227-
DOCKER_SOCK=/var/run/docker.sock
297+
if __dodocker system info --format '{{.SecurityOptions}}' | grep -qi rootless; then
298+
DOCKER_SOCK=/run/user/$(id -u)/docker.sock
299+
if [[ "${__docker_major_version}" -lt 29 \
300+
|| ( "${__docker_major_version}" -eq 29 && "${__docker_minor_version}" -lt 5 ) ]]; then
301+
__old_rootless_docker=1
302+
fi
303+
else
304+
DOCKER_SOCK=/var/run/docker.sock
305+
fi
228306
fi
229307
var=DOCKER_SOCK
230308
__get_value_from_env "${var}" "${__env_file}" "__value"
@@ -569,8 +647,8 @@ __check_compose_version() {
569647
# Compose V1 is in Ubuntu 22.04 and 24.04. The Compose version check can be removed when Ubuntu 24.04 goes EOL in 2029.
570648

571649
# Check for Compose V2+ (docker compose) vs Compose V1 (docker-compose)
572-
if __dodocker compose version >/dev/null 2>&1; then
573-
__compose_version=$(__dodocker compose version | sed -n -E -e "s/.*version [v]?([0-9.-]*).*/\1/ip")
650+
if ${__docker_sudo} ${__docker_exe} compose version >/dev/null 2>&1; then
651+
__compose_version=$(${__docker_sudo} ${__docker_exe} compose version | sed -n -E -e "s/.*version [v]?([0-9.-]*).*/\1/ip")
574652
__compose_major=${__compose_version%%.*}
575653
__compose_minor=${__compose_version#*.}
576654
__compose_minor=${__compose_minor%%.*}
@@ -909,7 +987,11 @@ __optimize_host() {
909987
local memtotal
910988

911989
echo
912-
docker_root=$(__dodocker system info --format '{{.DockerRootDir}}')
990+
if dpkg-query -W -f='${Status}' podman 2>/dev/null | grep -q "ok installed"; then
991+
docker_root=$(__dodocker system info --format '{{.Store.GraphRoot}}')
992+
else
993+
docker_root=$(__dodocker system info --format '{{.DockerRootDir}}')
994+
fi
913995
if command -v findmnt >/dev/null; then
914996
docker_mount=$(findmnt -T "${docker_root}" -o TARGET -n)
915997
docker_mount_opts=$(findmnt -T "${docker_root}" -o OPTIONS -n 2>/dev/null)
@@ -1000,6 +1082,11 @@ __install_docker() {
10001082
exit 70
10011083
fi
10021084

1085+
if dpkg-query -W -f='${Status}' podman 2>/dev/null | grep -q "ok installed"; then
1086+
echo "Found podman. Will not install Docker, as it would conflict."
1087+
return
1088+
fi
1089+
10031090
if [[ -z "$(command -v docker)" ]]; then
10041091
${__auto_sudo} install -m 0755 -d /etc/apt/keyrings
10051092
${__auto_sudo} curl -fsSL https://download.docker.com/linux/${repo}/gpg -o /etc/apt/keyrings/docker.asc
@@ -1115,8 +1202,12 @@ __get_docker_free_space() {
11151202
if [[ "$OSTYPE" = "darwin"* ]]; then # macOS doesn't expose docker root dir to the OS
11161203
__free_space=$(__dodocker run --rm -v macos-space-check:/dummy busybox df -P /dummy | awk '/[0-9]%/{print $(NF-2)}')
11171204
else
1118-
__docker_dir=$(__dodocker system info --format '{{.DockerRootDir}}')
1119-
__free_space=$(df -P "${__docker_dir}" | awk '/[0-9]%/{print $(NF-2)}')
1205+
if [[ "${__docker_exe}" = "podman" ]]; then
1206+
__docker_dir=$(__dodocker system info --format '{{.Store.GraphRoot}}')
1207+
else
1208+
__docker_dir=$(__dodocker system info --format '{{.DockerRootDir}}')
1209+
fi
1210+
__free_space=$(${__docker_sudo} df -P "${__docker_dir}" | awk '/[0-9]%/{print $(NF-2)}') # Allow for rootful podman
11201211
fi
11211212

11221213
regex='^[0-9]+$'
@@ -1125,7 +1216,7 @@ __get_docker_free_space() {
11251216
if [[ "$OSTYPE" = "darwin"* ]]; then
11261217
echo "df reports $(__dodocker run --rm -v macos-space-check:/dummy busybox df -P /dummy) and __free_space is ${__free_space}"
11271218
else
1128-
echo "df reports $(df -P "${__docker_dir}") and __free_space is ${__free_space}"
1219+
echo "df reports $(${__docker_sudo} df -P "${__docker_dir}") and __free_space is ${__free_space}" # Allow for rootful podman
11291220
fi
11301221
exit 70
11311222
fi
@@ -1138,7 +1229,7 @@ __display_docker_dir() {
11381229
__dodocker run --rm -v macos-space-check:/dummy busybox df -h /dummy
11391230
else
11401231
echo "Here's total and used space on ${__docker_dir}"
1141-
df -h "${__docker_dir}"
1232+
${__docker_sudo} df -h "${__docker_dir}" # Allow for rootful podman
11421233
fi
11431234
}
11441235

@@ -5064,8 +5155,8 @@ __query_web3signer() {
50645155

50655156
__query_grafana() {
50665157
if whiptail --title "Grafana" --yesno "Do you want to use Grafana dashboards?" 10 65; then
5067-
if [[ "$OSTYPE" = "darwin"* ]] || __dodocker system info --format '{{json .SecurityOptions}}' | grep -qi rootless; then
5068-
# macOS doesn't do well with / bind mount - leave node-exporter and cadvisor off by default. Also detect rootless Docker
5158+
if [[ "$OSTYPE" = "darwin"* ]] || { [[ "${__docker_exe}" = "podman" ]] && ! systemctl status podman.socket >/dev/null 2>&1 ;} || __dodocker system info --format '{{json .SecurityOptions}}' 2>/dev/null | grep -qi rootless; then
5159+
# macOS doesn't do well with / bind mount - leave node-exporter and cadvisor off by default. Also detect rootless Docker/Podman
50695160
CORE_FILES+=":grafana-rootless.yml:grafana-shared.yml"
50705161
else
50715162
CORE_FILES+=":grafana.yml:grafana-shared.yml"

ethrex.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
x-logging: &logging
22
logging:
3-
driver: json-file
3+
driver: ${LOG_DRIVER}
44
options:
5-
max-size: 100m
6-
max-file: "3"
7-
tag: '{{.ImageName}}|{{.Name}}|{{.ImageFullID}}|{{.FullID}}'
5+
max-size: ${LOG_MAX_SIZE}
6+
max-file: ${LOG_MAX_FILE}
7+
tag: ${LOG_TAG}
88

99
services:
1010
execution:

0 commit comments

Comments
 (0)