mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-26 21:33:05 +00:00
The new container_save and container_load functions can be used to
save and load container images.
container_save
Save a container image to a local file.
Example: container_save "${name}"
container_load
Load a container image from an tar archive.
Example: local_image=$(container_load "${archive}")
250 lines
6.0 KiB
Bash
250 lines
6.0 KiB
Bash
#!/bin/bash -eu
|
|
# This file is meant to be source'd by other scripts
|
|
|
|
SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"
|
|
TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"
|
|
|
|
# shellcheck disable=SC1091
|
|
. "${SCRIPTDIR}/shdefaults"
|
|
|
|
# shellcheck disable=SC1091
|
|
. "${TOPDIR}/utils/shfun"
|
|
|
|
container_create() {
|
|
local name=${1}
|
|
local image=${2}
|
|
shift 2
|
|
declare -a extra_opts
|
|
readarray -t extra_opts < \
|
|
<(sed -e "s/-/--cap-drop=/g" -e "s/+/--cap-add=/g" \
|
|
<<< "$(printf '%s\n' "${CAP_DEFAULTS[@]}")")
|
|
for opt in "$@"
|
|
do
|
|
[ -z "${opt}" ] && continue
|
|
case "${opt}" in
|
|
hostname=*) extra_opts+=("--${opt}") ;;
|
|
cpus=*) extra_opts+=("--${opt}") ;;
|
|
memory=*) extra_opts+=("--${opt}") ;;
|
|
capabilities=*) extra_opts+=("--cap-add=${opt##*=}") ;;
|
|
volume=*) extra_opts+=("--volume=${opt##*=}") ;;
|
|
*) log error "container_create: Invalid option: ${opt}" ;;
|
|
esac
|
|
done
|
|
|
|
# ensure default values are set
|
|
[[ " ${extra_opts[*]} " =~ " --cpus=" ]] || extra_opts+=("--cpus=2")
|
|
[[ " ${extra_opts[*]} " =~ " --hostname=" ]] \
|
|
|| extra_opts+=("--hostname=ipaserver.test.local")
|
|
|
|
log info "= Creating ${name} ="
|
|
podman create \
|
|
--security-opt label=disable \
|
|
--network bridge:interface_name=eth0 \
|
|
--systemd true \
|
|
--name "${name}" \
|
|
--memory-swap -1 \
|
|
--no-hosts \
|
|
--replace \
|
|
"${extra_opts[@]}" \
|
|
"${image}"
|
|
echo
|
|
}
|
|
|
|
container_start() {
|
|
local name="${1}"
|
|
|
|
log info "= Starting ${name} ="
|
|
podman start "${name}"
|
|
# Add host entry to /etc/hosts
|
|
ip=$(podman inspect "${name}" --format "{{.NetworkSettings.IPAddress}}")
|
|
hostname=$(podman inspect "${name}" --format "{{.Config.Hostname}}")
|
|
if [ -n "${ip}" ] && [ -n "${hostname}" ]; then
|
|
cmd=$(cat <<EOF
|
|
sed -i -E "/\s+${hostname}(\s|$)/d" /etc/hosts
|
|
echo -e "$ip\t${hostname} ${hostname%%.*}" >> /etc/hosts
|
|
EOF
|
|
)
|
|
podman exec "${name}" bash -c "$cmd"
|
|
fi
|
|
# Ensure /etc/shadow is readable
|
|
podman exec "${name}" bash -c "chmod u+r /etc/shadow"
|
|
echo
|
|
}
|
|
|
|
container_stop() {
|
|
local name="${1}"
|
|
|
|
log info "= Stopping ${name} ="
|
|
podman stop "${name}"
|
|
echo
|
|
}
|
|
|
|
container_wait_for_journald() {
|
|
local name=${1}
|
|
|
|
log info "= Waiting till systemd-journald is running ="
|
|
max=20
|
|
wait=2
|
|
count=0
|
|
while ! podman exec "${name}" ps -x | grep -q "systemd-journald"
|
|
do
|
|
if [ $count -ge $max ]; then
|
|
die "Timeout: systemd-journald is not starting up"
|
|
fi
|
|
count=$((count+1))
|
|
log info "Waiting ${wait} seconds .."
|
|
sleep ${wait}
|
|
done
|
|
log info "done"
|
|
echo
|
|
}
|
|
|
|
container_wait_up() {
|
|
local name="${1}"
|
|
|
|
log info "= Waiting till all services are started ="
|
|
max=20
|
|
wait=15
|
|
count=0
|
|
while podman exec "${name}" systemctl list-jobs | \
|
|
grep -qvi "no jobs running"
|
|
do
|
|
if [ $count -ge $max ]; then
|
|
die "Timeout: Services are not starting up"
|
|
fi
|
|
count=$((count+1))
|
|
log info "Waiting ${wait} seconds .."
|
|
sleep ${wait}
|
|
done
|
|
log info "done"
|
|
echo
|
|
}
|
|
|
|
container_build() {
|
|
local tag="${1}"
|
|
local file="${2}"
|
|
local dir="${3}"
|
|
|
|
log info "= Building ${tag} ="
|
|
podman build -t "${tag}" -f "${file}" "${dir}"
|
|
echo
|
|
}
|
|
|
|
container_commit() {
|
|
local name="${1}"
|
|
local image="${2}"
|
|
|
|
log info "= Committing \"${image}\" ="
|
|
podman commit "${name}" "${image}"
|
|
echo
|
|
}
|
|
|
|
container_exec() {
|
|
local name="${1}"
|
|
shift 1
|
|
|
|
# "@Q" is only needed for the log output, the exec command is properly
|
|
# working without also for args containing spaces.
|
|
log info "= Executing \"${*@Q}\" ="
|
|
podman exec -t "${name}" "${@}"
|
|
echo
|
|
}
|
|
|
|
container_remove_image_if_exists()
|
|
{
|
|
# In older (as in Ubuntu 22.04) podman versions,
|
|
# 'podman image rm --force' fails if the image
|
|
# does not exist.
|
|
local tag_to_remove="${1}"
|
|
|
|
if podman image exists "${tag_to_remove}"
|
|
then
|
|
log info "= Cleanup ${tag_to_remove} ="
|
|
podman image rm "${tag_to_remove}" --force
|
|
echo
|
|
fi
|
|
}
|
|
|
|
container_get_state()
|
|
{
|
|
local name="${1}"
|
|
|
|
state=$(podman ps -q --all --format "{{.State}}" --filter "name=${name}")
|
|
echo "${state}"
|
|
}
|
|
|
|
container_pull() {
|
|
local source="${1}"
|
|
|
|
image=$(podman pull "${source}")
|
|
echo "${image}"
|
|
}
|
|
|
|
container_image_list() {
|
|
local source="${1}"
|
|
|
|
# Append "$" for an exact match if the source does not end with ":" to
|
|
# search for the repo only.
|
|
if [[ ${source} != *: ]]; then
|
|
source="${source}$"
|
|
fi
|
|
image=$(podman image list --format "{{ .Repository }}:{{ .Tag }}" | \
|
|
grep "^${source}")
|
|
echo "${image}"
|
|
}
|
|
|
|
container_check() {
|
|
[ -n "$(command -v "podman")" ] || die "podman is required."
|
|
}
|
|
|
|
container_copy() {
|
|
local name="${1}"
|
|
local source="${2}"
|
|
local destination="${3}"
|
|
|
|
log info "= Copying ${source} to ${name}:${destination} ="
|
|
podman cp "${source}" "${name}:${destination}"
|
|
echo
|
|
}
|
|
|
|
container_fetch() {
|
|
local name="${1}"
|
|
local source="${2}"
|
|
local destination="${3}"
|
|
|
|
log info "= Copying ${name}:${source} to ${destination} ="
|
|
podman cp "${name}:${source}" "${destination}"
|
|
echo
|
|
}
|
|
|
|
container_tee() {
|
|
local name=${1}
|
|
local destination=${2}
|
|
tmpfile=$(mktemp /tmp/container-temp.XXXXXX)
|
|
|
|
log info "= Creating ${name}:${destination} from stdin ="
|
|
cat - > "${tmpfile}"
|
|
podman cp "${tmpfile}" "${name}:${destination}"
|
|
rm "${tmpfile}"
|
|
echo
|
|
}
|
|
|
|
container_save() {
|
|
local name=${1}
|
|
|
|
archive="${name}.tar"
|
|
log info "= Saving ${name} to ${archive} ="
|
|
# podman is not able to overwrite the archive
|
|
[ -f "${archive}" ] && rm "${archive}"
|
|
podman save -o "${archive}" "${name}"
|
|
echo
|
|
}
|
|
|
|
container_load() {
|
|
local name=${1}
|
|
|
|
image_name=$(podman load -q -i "${name}" | sed -e "s/^Loaded image: //")
|
|
image=$(podman image list -q "${image_name}")
|
|
echo "$image"
|
|
}
|