Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions enroot.in
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,11 @@ enroot::usage() {
podman://IMAGE[:TAG] Import a Docker image from a local podman repository

Options:
-a, --arch Architecture of the image (defaults to host architecture)
-o, --output Name of the output image file (defaults to "URI.sqsh")
-a, --arch Architecture of the image (defaults to host architecture)
-o, --output Name of the output image file (defaults to "URI.sqsh")
-x, --extract-mode Determines the way the image is extracted from a local Podman repository.
This option is ignored when importing images from registries or the Docker daemon.
Accepted values: tar, mount. Defaults to "tar".
EOF
;;
digest)
Expand Down Expand Up @@ -349,7 +352,7 @@ enroot::digest() {
}

enroot::import() {
local uri= filename= arch=
local uri= filename= arch= extract_mode=tar

while [ $# -gt 0 ]; do
case "$1" in
Expand All @@ -373,6 +376,16 @@ enroot::import() {
filename="${1#*=}"
shift
;;
-x|--extract-mode)
[ -z "${2-}" ] && enroot::usage import 1
extract_mode="$2"
shift 2
;;
--extract-mode=*)
[ -z "${1#*=}" ] && enroot::usage import 1
extract_mode="${1#*=}"
shift
;;
-h|--help)
enroot::usage import 0 ;;
--)
Expand All @@ -388,7 +401,7 @@ enroot::import() {
fi
uri="$1"

runtime::import "${uri}" "${filename}" "${arch}"
runtime::import "${uri}" "${filename}" "${extract_mode}" "${arch}"
}

enroot::load() {
Expand Down
44 changes: 35 additions & 9 deletions src/docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,31 @@ docker::load() (
tar --numeric-owner -C rootfs/ --mode=u-s,g-s -cpf - . | tar --numeric-owner -C '${name}/' -xpf -"
)

docker::daemon::_config_squash() {
local -r engine="$1" image="$2" arch="$3" rootfs="$4" filename="$5"
"${engine}" inspect "${image}" | common::jq '.[] | with_entries(.key|=ascii_downcase)' > config
docker::configure "${rootfs}" config "${arch}"

# Create the final squashfs filesystem.
common::log INFO "Creating squashfs filesystem..." NL
mksquashfs "${rootfs}" "${filename}" -all-root ${TTY_OFF+-no-progress} -processors "${ENROOT_MAX_PROCESSORS}" ${ENROOT_SQUASH_OPTIONS} >&2
}

podman::_mount_squash() {
set -euo pipefail
shopt -s lastpipe
local -r image="$1" arch="$2" container_name="$3" filename="$4"
local rootfs=

rootfs=$(podman mount "${container_name}")
docker::daemon::_config_squash podman "${image}" "${arch}" "${rootfs}" "${filename}"
podman unmount "${container_name}"
}

docker::daemon::import() (
local -r uri="$1"
local filename="$2" arch="$3"
local -r extract_mode="$4"
local image= tmpdir= engine=

case "${uri}" in
Expand Down Expand Up @@ -592,14 +614,18 @@ docker::daemon::import() (
common::log

# Extract and configure the rootfs.
common::log INFO "Extracting image content..."
mkdir rootfs
"${engine}" export "${PWD##*/}" | tar -C rootfs --warning=no-timestamp --anchored --exclude='dev/*' --exclude='.dockerenv' -px
common::fixperms rootfs
"${engine}" inspect "${image}" | common::jq '.[] | with_entries(.key|=ascii_downcase)' > config
docker::configure rootfs config "${arch}"
if [[ "${engine}" == "podman" ]] && [[ "${extract_mode}" == "mount" ]]; then
common::log INFO "Mounting image from Podman container..."
printf -v cmd "source %q/docker.sh && podman::_mount_squash %q %q %q %q" "${ENROOT_LIBRARY_PATH}" "${image}" "${arch}" "${PWD##*/}" "${filename}"
podman unshare bash -c "$cmd"
else
common::log INFO "Extracting image content..."
mkdir rootfs
"${engine}" export "${PWD##*/}" | tar -C rootfs --warning=no-timestamp --anchored --exclude='dev/*' --exclude='.dockerenv' -px
common::fixperms rootfs
docker::daemon::_config_squash "${engine}" "${image}" "${arch}" rootfs "${filename}"
fi

# Create the final squashfs filesystem.
common::log INFO "Creating squashfs filesystem..." NL
mksquashfs rootfs "${filename}" -all-root ${TTY_OFF+-no-progress} -processors "${ENROOT_MAX_PROCESSORS}" ${ENROOT_SQUASH_OPTIONS} >&2
# Cleanup the container created to extract the rootfs
"${engine}" rm "${PWD##*/}"
)
11 changes: 8 additions & 3 deletions src/runtime.sh
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,13 @@ runtime::digest() {
}

runtime::import() {
local -r uri="$1" filename="$2"
local arch="$3"
local -r uri="$1" filename="$2" extract_mode="$3"
local arch="${4-}"

# Check the extract mode value.
if [[ "${extract_mode}" != "tar" ]] && [[ "${extract_mode}" != "mount" ]]; then
common::err "Invalid extract mode: ${extract_mode}"
fi

# Use the host architecture as the default.
if [ -z "${arch}" ]; then
Expand All @@ -454,7 +459,7 @@ runtime::import() {
docker://*)
docker::import "${uri}" "${filename}" "${arch}" ;;
dockerd://* | podman://*)
docker::daemon::import "${uri}" "${filename}" "${arch}" ;;
docker::daemon::import "${uri}" "${filename}" "${arch}" "${extract_mode}" ;;
*)
common::err "Invalid argument: ${uri}" ;;
esac
Expand Down