#!/bin/bash #----------------------------------------------------------------------------------------------------------------------------------- # # Mk Base Image # Copyright (C) 2026 Arnaud G. GIBERT # mailto:arnaud@rx3.net # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # #----------------------------------------------------------------------------------------------------------------------------------- # Includes #----------------------------------------------------------------------------------------------------------------------------------- . /usr/lib/rx3/default.bash set -e # Global Variable #----------------------------------------------------------------------------------------------------------------------------------- VERSION=1.0.0 CONTAINER_NAME="rx3-mageia9" TMP_DIR="/tmp/mk_base_image" ROOT_DIR="/var/tmp/base_root" for var in $(env | grep "LC_"); do unset ${var/=*/}; done LC_ALL='en_US.UTF-8' LANG='en_US.UTF-8' LANGUAGE='en_US.UTF-8:en_US:en' export LC_ALL LANG LANGUAGE LOCALTIME='Europe/Paris' NAME_SERVER_0='10.10.0.254 8.8.8.8' NAME_SERVER_1='10.10.0.254 8.8.8.8' MIRRORLIST_MGA='http://mirror.xor.rx3/mageia/distrib/9/x86_64 https://mirror.rx3.net/mageia/distrib/9/x86_64 ftp://ftp.proxad.net/mirrors/mageia.org/distrib/9/x86_64 http://distrib-coffee.ipsl.jussieu.fr/pub/linux/Mageia/distrib/9/x86_64' MIRRORLIST_RX3='http://mirror.xor.rx3/rx3/distrib/9/x86_64 https://mirror.rx3.net/rx3/distrib/9/x86_64' # Version #----------------------------------------------------------------------------------------------------------------------------------- function mbi_version_print() { echo "MBI Version: [${VERSION}]" } # Help #----------------------------------------------------------------------------------------------------------------------------------- function mbi_help_print() { mbi_version_print echo "usage: mpm [[-h | --help] | [-V | --version] | [-p | --post] | [-s | --strip] | [-u | --unstrip]] [-d | --direct] [-r | --root ] [-t | --tmp ] [-T | --test] [-v | --verbose]" } # Arg Parse #----------------------------------------------------------------------------------------------------------------------------------- function mbi_args_parse() { mode="default" verbose="false" dry_run="false" direct="false" tmp_args=$(getopt -o dhpr:Tt:suvV --long direct,help,post,root:,test,tmp:,strip,unstrip,verbose,version -- "$@") if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi # Note the quotes around `$tmp_args': they are essential! eval set -- "${tmp_args}" while true ; do case "$1" in # Path options -t|--tmp) shift; tmp_dir="$1"; shift;; -r|--root) shift; root_dir="$1"; shift;; # Options -d|--direct) direct="true"; shift;; # Mode switches -h|--help) mode="exit"; mbi_help_print; shift;; -s|--post) mode="post"; shift;; -s|--strip) mode="strip"; shift;; -u|--unstrip) mode="unstrip"; shift;; -V|--version) mode="exit"; mbi_version_print; shift;; # Global options -T|--test) dry_run="true"; shift;; -v|--verbose) verbose="true"; shift;; # --) shift; break;; *) echo "args_parse internal error [$1] !"; exit 1;; esac done } # Env Init #----------------------------------------------------------------------------------------------------------------------------------- function mbi_env_init() { root_clean="$1" if [[ -d "${tmp_dir}" ]] then err_echo "Removing Tmp Dir: [${tmp_dir}] content..." exec_cmd "echo rm -R \"${tmp_dir}/*\"" else err_echo "Creating Tmp Dir: [${tmp_dir}]..." exec_cmd "mkdir -p \"${tmp_dir}\"" fi if [[ "${direct}" == "true" ]] then if [[ -d "${root_dir}" ]] then if [[ "${root_clean}" == "true" ]] then err_echo "Removing Root Dir: [${root_dir}] content..." exec_cmd "echo rm -R \"${root_dir}/*\"" else err_echo "Keeping Root Dir content..." fi else if [[ "${root_clean}" == "true" ]] then err_echo "Creating Root Dir: [${root_dir}]..." exec_cmd "mkdir -p \"${root_dir}\"" else err_echo "Error: Root Dir: [${root_dir}] not found!" exit 1 fi fi else if [[ "${root_clean}" == "true" ]] then if [[ $( buildah ls | grep ${CONTAINER_NAME}) != "" ]] then exec_cmd "buildah rm \"${CONTAINER_NAME}\" >/dev/null" fi exec_cmd "buildah from --name \"${CONTAINER_NAME}\" scratch >/dev/null" exec_cmd "buildah config --label maintainer=\"Arnaud G. GIBERT \" \"${CONTAINER_NAME}\"" else if [[ $( buildah ls | grep ${CONTAINER_NAME}) == "" ]] then echo_err "buildah container: [${CONTAINER_NAME}] not found!" exit 1 fi fi if [[ "$BUILDAH_ISOLATION" != "rootless" ]] then err_echo "Unsharing..." exec_cmd 'buildah unshare "$0" "${orig_args[@]}"' exit $? fi root_dir=$(buildah mount ${CONTAINER_NAME}) fi } # Func Exec #----------------------------------------------------------------------------------------------------------------------------------- function mbi_func_exec() { func="$1" arg="$2" name="$3" if [[ "${direct}" != "true" ]] || [[ "${root_dir}" != "/" ]] then err_echo "Only direct ${name} and / Root Dir supported: Recall..." exec_cmd 'chroot "${root_dir}" '"mk_base_image ${arg} --direct --root / $([[ "${verbose}" == "true" ]] && echo " --verbose")" else set +e find / 2>/dev/null | grep -v -e "^/dev" -e "^/proc" -e "^/run" -e "^/sys/" >/root/before declare -f ${func} | sed -n '/^{/,/^}/p' | sed -e '1d;$d' -e 's/;$//' | grep -v -E '^$|^#' | while read -r line do exec_cmd "${line}" done find / 2>/dev/null | grep -v -e "^/dev" -e "^/proc" -e "^/run" -e "^/sys/" >/root/after fi } # Base Install Pre #----------------------------------------------------------------------------------------------------------------------------------- function mbi_base_install_pre() { exec_cmd 'urpmi --root ${root_dir} --force --no-install --no-recommends --nolock --reinstall --download-all ${tmp_dir} --downloader curl makedev filesystem curl urpmi rx3-base' exec_cmd 'rpm --root ${root_dir} --initdb' exec_cmd 'rpm --root ${root_dir} -Uvh --nodeps --noscripts ${tmp_dir}/rpms/filesystem*' exec_cmd 'rm ${tmp_dir}/rpms/filesystem*' exec_cmd 'rpm --root ${root_dir} -Uvh --nodeps --noscripts ${tmp_dir}/rpms/makedev*' exec_cmd 'rm ${tmp_dir}/rpms/makedev*' exec_cmd 'rpm --root ${root_dir} -Uvh --nodeps ${tmp_dir}/rpms/*' exec_cmd 'rm -R ${tmp_dir}' exec_cmd 'echo -e "LANG=${LANG}\nLANGUAGE=${LANGUAGE}\nLC_ALL=${LC_ALL}" >"${root_dir}/etc/locale.conf"' exec_cmd 'ln -s /usr/share/zoneinfo/${LOCALTIME} ${root_dir}/etc/localtime' # Enable Neworking exec_cmd 'echo -e "nameserver ${NAME_SERVER_0}\nnameserver ${NAME_SERVER_1}" >"${root_dir}/etc/resolv.conf"' exec_cmd 'echo -e "NETWORKING=yes" >"${root_dir}/etc/sysconfig/network"' exec_cmd 'cp $0 ${root_dir}/usr/sbin' } # Base Install Post #----------------------------------------------------------------------------------------------------------------------------------- function _mbi_base_install_post() { urpmi.addmedia --distrib --mirrorlist "${MIRRORLIST_MGA}" urpmi.addmedia --distrib --mirrorlist "${MIRRORLIST_RX3}" urpmi.update -a urpmi --force basesystem-minimal locales locales-en shared-mime-info vim-minimal mpm urpmi --force --auto-update } function mbi_base_install_post() { mbi_func_exec "_mbi_base_install_post" "--post" "post-installing" } # Base Strip #----------------------------------------------------------------------------------------------------------------------------------- function _mbi_base_strip() { # RPM force uninstall rpm -e dhcp-common dhcp-client cronie-anacron rpm -e --nodeps cracklib-dicts # Docker mounts tmpfs at /dev and procfs at /proc so we can remove them rm -rf /dev /proc 2>/tmp/null mkdir -p /dev /proc 2>/tmp/null # Keep only en_US.UTF8 locale rm -rf /usr/share/locale/!("en_US.UTF-8"|"locale.alias"|"locale-archive") rm -rf /usr/{{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive} # Docs rm -rf /usr/share/{man,doc,info,gnome/help} # sln rm -rf /sbin/sln # ldconfig rm -rf /etc/ld.so.cache /var/cache/ldconfig mkdir -p --mode=0755 /var/cache/ldconfig # UDev rm -rf /usr/lib/udev rm -rf /etc/udev/hwdb.bin rm -rf /usr/lib/.build-id # Cache & Tmp rm -rf /var/cache/urpmi/rpms 2>/tmp/null rm -rf /tmp/* } function mbi_base_strip() { mbi_func_exec "_mbi_base_strip" "--strip" "stripping" } # Base UnStrip #----------------------------------------------------------------------------------------------------------------------------------- function _mbi_base_unstrip() { urpmi.update -a # Install deinstalled packages urpmi --force dhcp-common dhcp-client cronie-anacron cracklib-dicts # Force reinstall all packages urpmi --force --replacepkgs $(rpm -qa | grep -v gpg-pubkey) # urpmi --force --replacepkgs glibc locales locales-en } function mbi_base_unstrip() { mbi_func_exec "_mbi_base_unstrip" "--unstrip" "unstripping" } # Main #----------------------------------------------------------------------------------------------------------------------------------- orig_args=("$@") root_dir="${ROOT_DIR}" tmp_dir="${TMP_DIR}" mbi_args_parse "$@" if [[ ${mode} == "exit" ]] then exit 0 fi #if [[ "${direct}" != "true" ]] #then # root_dir="???" #fi if [[ "${mode}" == "default" ]] then mbi_env_init "true" else mbi_env_init "false" fi err_echo "MBI: mode: [${mode}] verbose: [${verbose}] direct: [${direct}] dry_run: [${dry_run}] Root_Dir: [${root_dir}] Tmp_Dir: [${tmp_dir}]" case "${mode}" in "default") mbi_base_install_pre mbi_base_install_post mbi_base_strip ;; "post") mbi_base_install_post ;; "strip") mbi_base_strip ;; "unstrip") mbi_base_unstrip ;; esac