Last active
November 1, 2024 08:32
-
-
Save satmandu/6829f229d18363ddeaf52d4b43a80623 to your computer and use it in GitHub Desktop.
Updated ChromeOS docker container script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# chromeos_docker.sh | |
# Usage: | |
# chromeos_docker.sh recoveryfileurl name milestone arch | |
# or if image.bin already exists this works too: | |
# chromeos_docker.sh dummy name milestone arch | |
# (Default is not to delete the image after download.) | |
# e.g. | |
# Example for x86_64: | |
# chromeos_docker.sh https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_13816.82.0_nocturne_recovery_stable-channel_mp.bin.zip nocturne 90 x86_64 | |
# Example for armv7l: | |
# chromeos_docker.sh https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_13904.55.0_veyron-fievel_recovery_stable-channel_fievel-mp.bin.zip fievel 91 armv7l | |
# Examples for i686: | |
# chromeos_docker.sh https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_9334.72.0_x86-alex-he_recovery_stable-channel_alex-mp-v4.bin.zip alex 58 i686 | |
# chromeos_docker.sh https://dl.google.com/dl/edgedl/chromeos/recovery/chromeos_9334.72.0_x86-zgb-he_recovery_stable-channel_zgb-mp-v3.bin.zip zgb 58 i686 | |
# Recovery file update links are here: https://cros-updates-serving.appspot.com/ | |
# Note that you may need further steps if you are on an x86_64 machine. | |
# See https://www.stereolabs.com/docs/docker/building-arm-container-on-x86/ | |
# | |
# Note also you should have a registry setup. | |
# Instructions here: https://docs.docker.com/registry/deploying/ | |
# If you setup your registry with an ssl cert, you may have fewer problems. | |
# You can set the registry URL with the REPOSITORY env variable. | |
# e.g. export REPOSITORY="dockerserver:5000" | |
imageurl="${1}" | |
name="${2}" | |
milestone="${3}" | |
ARCH="${4}" | |
: "${outdir:=$(pwd)}" | |
: "${REPOSITORY:=127.0.0.1:5000}" | |
: "${PKG_CACHE:=$outdir/pkg_cache}" | |
echo " image url:${imageurl}" | |
echo " name: ${name}" | |
echo " milestone: ${milestone}" | |
echo " ARCH: ${ARCH}" | |
echo " REPOSITORY: ${REPOSITORY}" | |
echo "output root: ${outdir}" | |
echo " PKG_CACHE: ${PKG_CACHE}" | |
userid=$(id -un) | |
tmpdir=$(mktemp -d docker_XXXX -p "$(pwd)") | |
function abspath { | |
echo $(cd "$1" && pwd) | |
} | |
countdown() | |
( | |
IFS=: | |
set -- $* | |
secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} )) | |
while [ $secs -gt 0 ] | |
do | |
sleep 1 & | |
printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60)) | |
secs=$(( $secs - 1 )) | |
wait | |
done | |
echo | |
) | |
get_arch () { | |
if [[ ! -f "$ARCH/image.bin.${milestone}" ]] ; then | |
curl --retry 3 -Lf "$imageurl" -o "$ARCH"/image.bin.zip || ( echo "Download failed" && kill $$ ) | |
unzip -p "$ARCH"/image.bin.zip > "$ARCH"/image.bin."${milestone}" && rm "$ARCH"/image.bin.zip | |
fi | |
sudo kpartx -d "$ARCH"/image.bin."${milestone}" | |
rootpart=$(sudo kpartx -v -a "$ARCH"/image.bin."${milestone}" | grep 'p3\b' | awk '{print $3}') | |
if [[ -n $rootpart ]]; then | |
sudo umount /dev/mapper/"$rootpart" || true | |
sudo mount -o ro -t ext4 /dev/mapper/"$rootpart" "$tmpdir" | |
else | |
rootpart=$(losetup | grep image.bin."${milestone}" | awk '{print $1}') | |
[[ -n $rootpart ]] && sudo mount -o ro -t ext4 "$rootpart" "$tmpdir" | |
fi | |
[[ -z "$rootpart" ]] && (echo "The downloaded recovery in image.bin.${milestone} doesn't look right." && kill $$) | |
chromeos_arch=$(file "$tmpdir"/bin/bash | awk '{print $7}' | sed 's/,//g') | |
echo "chromeos_arch is $chromeos_arch" | |
if [[ "$chromeos_arch" == "x86-64" ]]; then | |
ARCH_LIB=lib64 | |
ARCH=x86_64 | |
CREW_LIB_PREFIX=$CREW_PREFIX/$ARCH_LIB | |
CREW_PREFIX=/usr/local | |
DOCKER_PLATFORM=amd64 | |
MARCH=x86-64 | |
PLATFORM="linux/amd64" | |
SETARCH_ARCH=x86_64 | |
elif [[ "$chromeos_arch" == "ARM" ]]; then | |
ARCH=armv7l | |
ARCH_LIB=lib | |
CREW_LIB_PREFIX=$CREW_PREFIX/$ARCH_LIB | |
CREW_PREFIX=/usr/local | |
DOCKER_PLATFORM=armv7 | |
MARCH=armv7-a | |
PLATFORM="linux/arm/v7" | |
SETARCH_ARCH=armv7l | |
elif [[ "$chromeos_arch" == "Intel" ]]; then | |
ARCH=i686 | |
ARCH_LIB=lib | |
CREW_LIB_PREFIX=$CREW_PREFIX/$ARCH_LIB | |
CREW_PREFIX=/usr/local | |
DOCKER_PLATFORM=amd64 | |
MARCH=i686 | |
PLATFORM="linux/amd64" | |
SETARCH_ARCH=i686 | |
elif [[ "$chromeos_arch" == "file" ]]; then | |
echo "Error in determining image architecture." | |
exit 1 | |
fi | |
} | |
import_to_Docker () { | |
if ! docker image ls | grep "${userid}"/crewbase-"${name}"-${ARCH}.m"${milestone}" ; then | |
cd "$tmpdir" && sudo tar -c . | docker import --platform ${PLATFORM} - "${userid}"/crewbase-"${name}"-${ARCH}.m"${milestone}" | |
fi | |
cd .. | |
sudo umount "$tmpdir" | |
rmdir "$tmpdir" | |
#rm image.bin."${milestone}" | |
} | |
build_dockerfile () { | |
cd "${outdir}" || exit | |
cat <<EOF > ./${ARCH}/Dockerfile | |
ARG UID=1000 | |
FROM ${REPOSITORY}/crewbase-${name}-${ARCH}.m${milestone}:${DOCKER_PLATFORM} | |
#ENV LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$CREW_LIB_PREFIX | |
# Set githup repo information being synced from for install. | |
ENV REPO=chromebrew | |
ENV OWNER=skycocker | |
ENV BRANCH=master | |
ENV ARCH=$ARCH | |
ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin | |
ENV HOME=/home/chronos/user/ | |
ENV LANG=en_US.UTF-8 | |
ENV LC_all=en_US.UTF-8 | |
ENV XML_CATALOG_FILES=/usr/local/etc/xml/catalog | |
SHELL ["/bin/bash", "-o", "pipefail", "-c"] | |
RUN passwd -d chronos && \ | |
echo "chronos ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ | |
echo -e 'set -a\nCREW_TESTING_REPO=https://github.com/satmandu/chromebrew.git\nCREW_TESTING_BRANCH=master\nCREW_TESTING=0\nset +a' >> /home/chronos/user/.profile && chown chronos:chronos /home/chronos/user/.profile && \ | |
echo -e '[[ -e /usr/local/etc/profile ]] && source /usr/local/etc/profile\nset -a\nCFLAGS="-march=$MARCH"\n: "\${LANG:=en_US.UTF-8}"\n: "\${LC_ALL:=en_US.UTF-8}"\n[[ -d "/output/pkg_cache" ]] && CREW_CACHE_DIR=/output/pkg_cache\n[[ -n "\$CREW_CACHE_DIR" ]] && CREW_CACHE_ENABLED=1\nset +a\n' >> /home/chronos/user/.bashrc && \ | |
chown chronos:chronos /home/chronos/user/.bashrc | |
# For testing a local install.sh script | |
# RUN --mount=type=bind,target=/input cp /input/install.sh.test /home/chronos/user/install.sh | |
RUN curl -Ls https://github.com/\$OWNER/\$REPO/raw/\$BRANCH/install.sh -o /home/chronos/user/install.sh && \ | |
chown chronos /home/chronos/user/install.sh && \ | |
chmod +x /home/chronos/user/install.sh | |
SHELL ["/usr/bin/sudo", "-E", "-n", "BASH_ENV=/home/chronos/user/.bashrc", "-u", "chronos", "/bin/bash", "-c"] | |
RUN --mount=type=bind,target=/input PATH=/usr/local/bin:/usr/local/sbin:\$PATH \ | |
CREW_CACHE_DIR=/input/pkg_cache \ | |
CREW_CACHE_ENABLED=1 \ | |
OWNER=\$OWNER \ | |
BRANCH=\$BRANCH \ | |
/bin/bash /home/chronos/user/install.sh || true | |
RUN --mount=type=bind,target=/input yes | \ | |
PATH=/usr/local/bin:/usr/local/sbin:\$PATH \ | |
CREW_CACHE_DIR=/input/pkg_cache \ | |
CREW_CACHE_ENABLED=1 \ | |
crew install util_linux bash coreutils gcc11 || true | |
# We can use setarch now that util_linux is installed. | |
SHELL ["/usr/bin/sudo", "-E", "-n", "BASH_ENV=/home/chronos/user/.bashrc", "-u", "chronos", "setarch", "$SETARCH_ARCH", "/bin/bash", "-o", "pipefail", "-c"] | |
RUN --mount=type=bind,target=/input yes | \ | |
PATH=/usr/local/bin:/usr/local/sbin:\$PATH \ | |
CREW_CACHE_DIR=/input/pkg_cache \ | |
CREW_CACHE_ENABLED=1 \ | |
crew install psmisc buildessential || true | |
RUN gem update --silent -N --system && \ | |
gem install -N rubocop | |
SHELL ["/bin/bash", "-o", "pipefail", "-c"] | |
RUN echo -e "cd /usr/local/lib/crew/packages\ncrew update" >> /home/chronos/user/.bashrc | |
EOF | |
} | |
build_docker_image_with_local_registry () { | |
docker ps | |
echo "Tag & Push starting in ..." && countdown "00:00:01" | |
if ! docker pull ${REPOSITORY}/crewbase-"${name}"-${ARCH}.m"${milestone}" ; then | |
docker tag "${userid}"/crewbase-"${name}"-${ARCH}.m"${milestone}" ${REPOSITORY}/crewbase-"${name}"-${ARCH}.m"${milestone}":${DOCKER_PLATFORM} | |
docker push ${REPOSITORY}/crewbase-"${name}"-${ARCH}.m"${milestone}":${DOCKER_PLATFORM} | |
fi | |
} | |
make_cache_links () { | |
mkdir -p ./${ARCH}/pkg_cache | |
for i in $(cd pkg_cache && ls ./*${ARCH}*.*xz) | |
do | |
ln -f pkg_cache/"$i" ./${ARCH}/pkg_cache/"$i" 2>/dev/null || ( [[ ! -f ./${ARCH}/pkg_cache/$i ]] && cp pkg_cache/"$i" ./${ARCH}/pkg_cache/"$i" ) | |
done | |
} | |
build_docker_image () { | |
docker image ls | |
dangling_images=$(docker images --filter "dangling=true" -q --no-trunc) | |
[[ -n "$dangling_images" ]] && docker rmi -f $(docker images --filter "dangling=true" -q --no-trunc) | |
cp install.sh ./${ARCH}/ | |
buildx_cmd="env PROGRESS_NO_TRUNC=1 DOCKER_BUILDKIT=1 docker build --progress=plain --squash --no-cache --tag ${REPOSITORY}/crewbase-${name}.m${milestone}:${DOCKER_PLATFORM} ./${ARCH}/" | |
echo "$buildx_cmd" | |
$buildx_cmd || echo "Docker Build Error." | |
} | |
make_docker_image_script () { | |
dockercmd="docker run --rm -v ${PKG_CACHE}:/usr/local/tmp/packages -v \$(pwd):/output -h \$(hostname)-${ARCH} -it ${REPOSITORY}/crewbase-${name}.m${milestone}:${DOCKER_PLATFORM} /usr/local/bin/setarch ${SETARCH_ARCH} sudo -i -u chronos /usr/local/bin/bash -i" | |
[[ -f $(abspath "${outdir}")/crewbase-${name}-${ARCH}.m${milestone}.sh ]] && rm $(abspath "${outdir}")/crewbase-"${name}"-${ARCH}.m"${milestone}".sh | |
echo -e "#!/bin/bash\n$dockercmd" > $(abspath "${outdir}")/crewbase-"${name}"-${ARCH}.m"${milestone}".sh && chmod +x $(abspath "${outdir}")/crewbase-"${name}"-${ARCH}.m"${milestone}".sh | |
} | |
enter_docker_image () { | |
echo "Running \"$dockercmd\" from \"$(abspath "${outdir}")/crewbase-${name}-${ARCH}.m${milestone}.sh\"" | |
echo "Entering in..." && countdown "00:00:30" | |
exec "$(abspath "${outdir}")/crewbase-${name}-${ARCH}.m${milestone}.sh" | |
} | |
main () { | |
get_arch | |
mkdir "${outdir}"/{autobuild,built,packages,preinstall,postinstall,src_cache,tmp,${ARCH}} &> /dev/null | |
import_to_Docker | |
# This enables ipv6 for docker container | |
if ! docker container ls | grep ipv6nat ; then | |
docker run -d --name ipv6nat --privileged --network host --restart unless-stopped -v /var/run/docker.sock:/var/run/docker.sock:ro -v /lib/modules:/lib/modules:ro robbertkl/ipv6nat | |
fi | |
build_dockerfile | |
build_docker_image_with_local_registry | |
make_cache_links | |
build_docker_image | |
make_docker_image_script | |
[[ -z "$JUST_BUILD" ]] && enter_docker_image | |
} | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment