diff --git a/create-docker.sh b/create-docker.sh new file mode 100755 index 0000000000000000000000000000000000000000..4e9de587a44f4dbcf229fad2e02fe4e30986fde8 --- /dev/null +++ b/create-docker.sh @@ -0,0 +1,272 @@ +#!/usr/bin/env bash +# +# Create a base CentOS Docker image. +# +# This script is useful on systems with yum installed (e.g., building +# a CentOS image on CentOS). See contrib/mkimage-rinse.sh for a way +# to build CentOS images on other systems. + +set -e + +usage() { + cat << EOOPTS +$(basename $0) [OPTIONS] +OPTIONS: + -p "" The list of packages to install in the container. + The default is blank. Can use multiple times. + -g "" The groups of packages to install in the container. + The default is "Core". Can use multiple times. + -t Specify Tag information. + default is reffered at /etc/{kos,anolis,system}-release + -s "" Source file path that need to add into container. + maybe file or directory. + -d "" Target directory path that filesource would be in the container. + Only directory, default is / of container. + if is relative path, would be at / of container. +EOOPTS + exit 1 +} + +#install docker +if [ -z "$(rpm -qa docker)" ]; then + yum install -y docker +fi +if [ ! -z "$(systemctl list-units|grep docker)" ]; then + systemctl start docker + echo "start docker service" +fi +if [ $? != 0 ];then + echo "Error:check local yum conf and try again! docker RPM is in PowerTools repo." + exit 1 +fi + + +# option defaults +yum_config=/etc/yum.conf +if [ -f /etc/dnf/dnf.conf ] && command -v dnf &> /dev/null; then + yum_config=/etc/dnf/dnf.conf + alias yum=dnf +fi +# for names with spaces, use double quotes (") as install_groups_or_modules=('Core' '"Compute Node"') +install_groups_or_modules=() +install_packages=() +version= +filesrc="" +filetarget="" +has_error=0 +while getopts ":s:d:y:p:g:t:h" opt; do + case $opt in + h) + usage + ;; + p) + install_packages+=("$OPTARG") + ;; + g) + install_groups_or_modules+=("$OPTARG") + ;; + t) + version="$OPTARG" + ;; + s) + filesrc=` echo "$OPTARG"|sed 's/ //g'` + if [ ! -e $filesrc ]; then + echo "file [$filesrc] does not exist" + has_error=1 + fi + ;; + d) + filetarget=`echo "$OPTARG"|sed 's/ //g'` + valid_char_for_filetarget='^[a-zA-Z0-9 /_\.\+\-]\+$' + if [ ! -z "$filetarget" ]; then + if echo "$filetarget" | grep "$valid_char_for_filetarget"; then + echo " " + else + echo "Error: -d's value contains incorrect data, and valid chars are: upper and lower case letters numbers - _ + ." + has_error=1 + fi + fi + ;; + :) + echo "Warning: -$OPTARG require argument" + usage + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + ;; + esac +done +name=`cat /etc/os-release | grep "^NAME" | cut -d \" -f2` +name=`echo $name|sed 's/ /-/g'|awk '{print tolower($0)}'` + +if [[ "$filetarget" != "" && "$filesrc" == "" ]];then + echo "-s must have value when -d has value" + has_error=1 +fi +if [[ "$filesrc" != "" && "$filetarget" == "" ]];then + echo "-d must have value when -s has value, use /root by default." + filetarget="/root/" +fi +if [ $has_error != 0 ]; then + echo "exit because error" + exit 1 +fi + +# default to Core group if not specified otherwise +if [ ${#install_groups_or_modules[*]} -eq 0 ]; then + install_groups_or_modules=('Core') +fi + +target=$(mktemp -d --tmpdir $(basename $0).XXXXXX) + +set -x + +mkdir -m 755 "$target"/dev +mknod -m 600 "$target"/dev/console c 5 1 +mknod -m 600 "$target"/dev/initctl p +mknod -m 666 "$target"/dev/full c 1 7 +mknod -m 666 "$target"/dev/null c 1 3 +mknod -m 666 "$target"/dev/ptmx c 5 2 +mknod -m 666 "$target"/dev/random c 1 8 +mknod -m 666 "$target"/dev/tty c 5 0 +mknod -m 666 "$target"/dev/tty0 c 4 0 +mknod -m 666 "$target"/dev/urandom c 1 9 +mknod -m 666 "$target"/dev/zero c 1 5 + +# amazon linux yum will fail without vars set +if [ -d /etc/yum/vars ]; then + mkdir -p -m 755 "$target"/etc/yum + cp -a /etc/yum/vars "$target"/etc/yum/ +fi + +#fix 1 warning when install groups +cp /etc/os-release "$target"/etc/ + +set +e +set +x +if [[ -n "$install_groups_or_modules" ]]; then + install_groups=() + install_modules=() + for gm in ${install_groups_or_modules[@]}; + do + RESULT_g=`LANG=en_US.UTF-8 yum groupinfo "$gm" 2>&1 | grep "does not exist"` + if [ -n "$RESULT_g" ];then + RESULT_m=`LANG=en_US.UTF-8 yum module info "$gm" 2>&1 | grep "No matching Modules to list"` + if [ -n "$RESULT_m" ];then + echo "Error: can't find $gm as a group or a module" + rm -rf "$target" + exit 1 + else + echo "find module:$gm" + install_modules+=("$gm") + fi + else + echo "find group:$gm" + install_groups+=("$gm") + fi + done + echo "groups: ${install_groups[@]}" + echo "modules: ${install_modules[@]}" +fi + +if [[ -n "$install_packages" ]]; then + for pp in ${install_packages[@]}; + do + RESULT_p=`LANG=en_US.UTF-8 yum info "$pp" 2>&1 | grep "No matching Packages to list"` + if [ -n "$RESULT_p" ];then + echo "Error: can't find $pp as a package" + rm -rf "$target" + exit 1 + fi + done + echo "packages:${install_packages[@]}" +fi + +set -e +set -x +if [[ -n "$install_groups" ]]; then + yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \ + --setopt=group_package_types=mandatory -y groupinstall "${install_groups[@]}" +fi +if [[ -n "$install_modules" ]]; then + yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \ + --setopt=group_package_types=mandatory -y module install "${install_modules[@]}" +fi +if [[ -n "$install_packages" ]]; then + yum -c "$yum_config" --installroot="$target" --releasever=/ --setopt=tsflags=nodocs \ + --setopt=group_package_types=mandatory -y install "${install_packages[@]}" +fi + +yum -c "$yum_config" --installroot="$target" -y clean all + +cat > "$target"/etc/sysconfig/network << EOF +NETWORKING=yes +HOSTNAME=localhost.localdomain +EOF + +# effectively: febootstrap-minimize --keep-zoneinfo --keep-rpmdb --keep-services "$target". +# locales +rm -rf "$target"/usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive} +# docs and man pages +rm -rf "$target"/usr/share/{man,doc,info,gnome/help} +# cracklib +rm -rf "$target"/usr/share/cracklib +# i18n +rm -rf "$target"/usr/share/i18n +# yum cache +rm -rf "$target"/var/cache/yum +mkdir -p --mode=0755 "$target"/var/cache/yum +# sln +rm -rf "$target"/sbin/sln +# ldconfig +rm -rf "$target"/etc/ld.so.cache "$target"/var/cache/ldconfig +mkdir -p --mode=0755 "$target"/var/cache/ldconfig + +#cp file to docker +if [ "$filetarget" != "" ]; then + if [ -e "$target/$filetarget" ];then + if [ ! -d "$target/$filetarget" ];then + echo "Error: filetarget must be directory!" + exit 2 + fi + else + mkdir -p "$target/$filetarget" + fi + cp -r $filesrc "$target/$filetarget" + if [ $? != 0 ];then + echo "Error: copy file into docker failed!" + exit 2 + fi +fi + +if [ -z "$version" ]; then + ls "$target"/etc/ + for file in "$target"/etc/{kos,anolis,system}-release; do + if [ -r "$file" ]; then + version="$(sed 's/^[^0-9\]*\([0-9.]\+\).*$/\1/' "$file")" + break + fi + done +fi + +if [ -z "$version" ]; then + echo >&2 "warning: cannot autodetect OS version, using '$name' as tag" + version=$name +fi +echo "name: $name version: $version" + +tar --numeric-owner -c -C "$target" . | docker import - $name:$version + +docker run -i -t --rm $name:$version /bin/bash -c 'echo success' + +date_str=$(date "+%Y%m%d%H%M%S") +RESULT_DIR="docker_images/$date_str" +if [ ! -e $RESULT_DIR ];then + mkdir -p $RESULT_DIR +fi +docker save -o "$RESULT_DIR/$name-$version.tar" $name:$version +docker rmi $name:$version + +rm -rf "$target" +echo "Info: docker image is [$RESULT_DIR/$name-$version.tar]"