[
  {
    "path": "README.md",
    "content": "arch-bootstrap\n==============\n\nBootstrap a base Arch Linux system from any GNU distro.\n\nNOTE: This script downloads packages from scratch. For a more simple approach (using archlinux-bootstrap-x86_64 files), check:\n\nhttps://wiki.archlinux.org/title/Install_Arch_Linux_from_existing_Linux\nhttps://github.com/wick3dr0se/archstrap\n\nInstall\n=======\n\n    # install -m 755 arch-bootstrap.sh /usr/local/bin/arch-bootstrap\n\nExamples\n=========\n\nCreate a base arch distribution in directory 'myarch' (currently running arch by default):\n\n    # arch-bootstrap myarch\n   \nThe same but use arch x86_64 and a given repository source:\n\n    # arch-bootstrap -a x86_64 -r \"ftp://ftp.archlinux.org\" myarch \n\nUsage\n=====\n\nOnce the process has finished, chroot to the destination directory (default user: root/root):\n\n    # chroot destination\n\nNote that some packages require some system directories to be mounted. Some of the commands you can try:\n\n    # mount --bind /proc myarch/proc\n    # mount --bind /sys myarch/sys\n    # mount --bind /dev myarch/dev\n    # mount --bind /dev/pts myarch/dev/pts\n    \nLicense\n=======\n\nThis project is licensed under the terms of the MIT license\n"
  },
  {
    "path": "arch-bootstrap.sh",
    "content": "#!/bin/bash\n#\n# arch-bootstrap: Bootstrap a base Arch Linux system using any GNU distribution.\n#\n# Dependencies: bash >= 4, coreutils, curl, sed, gawk, tar, gzip, chroot, xz, zstd.\n# Project: https://github.com/tokland/arch-bootstrap\n#\n# Install:\n#\n#   # install -m 755 arch-bootstrap.sh /usr/local/bin/arch-bootstrap\n#\n# Usage:\n#\n#   # arch-bootstrap destination\n#   # arch-bootstrap -a x86_64 -r ftp://ftp.archlinux.org destination-64\n#\n# And then you can chroot to the destination directory (user: root, password: root):\n#\n#   # chroot destination\n\nset -e -u -o pipefail\n\n# Packages needed by pacman (see get-pacman-dependencies.sh)\nPACMAN_PACKAGES=(\n  acl archlinux-keyring attr brotli bzip2 curl expat glibc gpgme libarchive\n  libassuan libgpg-error libnghttp2 libnghttp3 libssh2 lzo openssl pacman pacman-mirrorlist xz zlib\n  krb5 e2fsprogs keyutils libidn2 libunistring gcc-libs lz4 libpsl icu libunistring zstd libxml2\n)\nBASIC_PACKAGES=(${PACMAN_PACKAGES[*]} filesystem base)\nEXTRA_PACKAGES=(coreutils bash grep gawk file tar gzip systemd sed)\nDEFAULT_REPO_URL=\"http://mirrors.kernel.org/archlinux\"\nDEFAULT_ARM_REPO_URL=\"http://mirror.archlinuxarm.org\"\nDEFAULT_X86_REPO_URL=\"http://mirror.archlinux32.org\"\n\nstderr() { \n  echo \"$@\" >&2 \n}\n\ndebug() {\n  stderr \"--- $@\"\n}\n\nextract_href() {\n  sed -n '/<a / s/^.*<a [^>]*href=\"\\([^\\\"]*\\)\".*$/\\1/p'\n}\n\nfetch() {\n  curl -L -s \"$@\"\n}\n\nfetch_file() {\n  local FILEPATH=$1\n  shift\n  if [[ -e \"$FILEPATH\" ]]; then\n    curl -L -z \"$FILEPATH\" -o \"$FILEPATH\" \"$@\"\n  else\n    curl -L -o \"$FILEPATH\" \"$@\"\n  fi\n}\n\nuncompress() {\n  local FILEPATH=$1 DEST=$2\n  \n  case \"$FILEPATH\" in\n    *.gz) \n      tar xzf \"$FILEPATH\" -C \"$DEST\";;\n    *.xz) \n      xz -dc \"$FILEPATH\" | tar x -C \"$DEST\";;\n    *.zst)\n      zstd -dc \"$FILEPATH\" | tar x -C \"$DEST\";;\n    *)\n      debug \"Error: unknown package format: $FILEPATH\"\n      return 1;;\n  esac\n}  \n\n###\n\nget_default_repo() {\n  local ARCH=$1\n  if [[ \"$ARCH\" == arm* || \"$ARCH\" == aarch64 ]]; then\n    echo $DEFAULT_ARM_REPO_URL\n  elif [[ \"$ARCH\" == i*86 || \"$ARCH\" == pentium4 ]]; then\n    echo $DEFAULT_X86_REPO_URL\n  else\n    echo $DEFAULT_REPO_URL\n  fi\n}\n\nget_core_repo_url() {\n  local REPO_URL=$1 ARCH=$2\n  if [[ \"$ARCH\" == arm* || \"$ARCH\" == aarch64 || \"$ARCH\" == i*86 || \"$ARCH\" == pentium4 ]]; then\n    echo \"${REPO_URL%/}/$ARCH/core\"\n  else\n    echo \"${REPO_URL%/}/core/os/$ARCH\"\n  fi\n}\n\nget_template_repo_url() {\n  local REPO_URL=$1 ARCH=$2\n  if [[ \"$ARCH\" == arm* || \"$ARCH\" == aarch64 || \"$ARCH\" == i*86 || \"$ARCH\" == pentium4 ]]; then\n    echo \"${REPO_URL%/}/$ARCH/\\$repo\"\n  else\n    echo \"${REPO_URL%/}/\\$repo/os/$ARCH\"\n  fi\n}\n\nconfigure_pacman() {\n  local DEST=$1 ARCH=$2\n  debug \"configure DNS and pacman\"\n  cp \"/etc/resolv.conf\" \"$DEST/etc/resolv.conf\"\n  SERVER=$(get_template_repo_url \"$REPO_URL\" \"$ARCH\")\n  echo \"Server = $SERVER\" > \"$DEST/etc/pacman.d/mirrorlist\"\n}\n\nconfigure_minimal_system() {\n  local DEST=$1\n  \n  mkdir -p \"$DEST/dev\"\n  sed -ie 's/^root:.*$/root:$1$GT9AUpJe$oXANVIjIzcnmOpY07iaGi\\/:14657::::::/' \"$DEST/etc/shadow\"\n  touch \"$DEST/etc/group\"\n  echo \"bootstrap\" > \"$DEST/etc/hostname\"\n\n  rm -f \"$DEST/etc/mtab\"\n  echo \"rootfs / rootfs rw 0 0\" > \"$DEST/etc/mtab\"\n  test -e \"$DEST/dev/null\" || mknod \"$DEST/dev/null\" c 1 3\n  test -e \"$DEST/dev/random\" || mknod -m 0644 \"$DEST/dev/random\" c 1 8\n  test -e \"$DEST/dev/urandom\" || mknod -m 0644 \"$DEST/dev/urandom\" c 1 9\n\n  sed -i 's/^DownloadUser/#DownloadUser/' \"$DEST/etc/pacman.conf\"\n  sed -i \"s/^[[:space:]]*\\(CheckSpace\\)/# \\1/\" \"$DEST/etc/pacman.conf\"\n  sed -i \"s/^[[:space:]]*SigLevel[[:space:]]*=.*$/SigLevel = Never/\" \"$DEST/etc/pacman.conf\"\n}\n\nfetch_packages_list() {\n  local REPO=$1 \n  \n  debug \"fetch packages list: $REPO/\"\n  fetch \"$REPO/\" | extract_href | awk -F\"/\" '{print $NF}' | sort -rn ||\n    { debug \"Error: cannot fetch packages list: $REPO\"; return 1; }\n}\n\ninstall_pacman_packages() {\n  local BASIC_PACKAGES=$1 DEST=$2 LIST=$3 DOWNLOAD_DIR=$4\n  debug \"pacman package and dependencies: $BASIC_PACKAGES\"\n  \n  for PACKAGE in $BASIC_PACKAGES; do\n    local FILE=$(echo \"$LIST\" | grep -m1 \"^$PACKAGE-[[:digit:]].*\\(\\.gz\\|\\.xz\\|\\.zst\\)$\")\n    test \"$FILE\" || { debug \"Error: cannot find package: $PACKAGE\"; return 1; }\n    local FILEPATH=\"$DOWNLOAD_DIR/$FILE\"\n    \n    debug \"download package: $REPO/$FILE\"\n    fetch_file \"$FILEPATH\" \"$REPO/$FILE\"\n    debug \"uncompress package: $FILEPATH\"\n    uncompress \"$FILEPATH\" \"$DEST\"\n  done\n}\n\nconfigure_static_qemu() {\n  local ARCH=$1 DEST=$2\n  [[ \"$ARCH\" == arm* ]] && ARCH=arm\n  QEMU_STATIC_BIN=$(which qemu-$ARCH-static || echo )\n  [[ -e \"$QEMU_STATIC_BIN\" ]] ||\\\n    { debug \"no static qemu for $ARCH, ignoring\"; return 0; }\n  cp \"$QEMU_STATIC_BIN\" \"$DEST/usr/bin\"\n}\n\ninstall_packages() {\n  local ARCH=$1 DEST=$2 PACKAGES=$3\n  debug \"install packages: $PACKAGES\"\n  LC_ALL=C chroot \"$DEST\" /usr/bin/pacman \\\n    --noconfirm --arch $ARCH -Sy --overwrite \\* $PACKAGES\n}\n\nshow_usage() {\n  stderr \"Usage: $(basename \"$0\") [-q] [-a i486|i686|pentium4|x86_64|arm|aarch64] [-r REPO_URL] [-d DOWNLOAD_DIR] DESTDIR\"\n}\n\nmain() {\n  # Process arguments and options\n  test $# -eq 0 && set -- \"-h\"\n  local ARCH=\n  local REPO_URL=\n  local USE_QEMU=\n  local DOWNLOAD_DIR=\n  local PRESERVE_DOWNLOAD_DIR=\n  \n  while getopts \"qa:r:d:h\" ARG; do\n    case \"$ARG\" in\n      a) ARCH=$OPTARG;;\n      r) REPO_URL=$OPTARG;;\n      q) USE_QEMU=true;;\n      d) DOWNLOAD_DIR=$OPTARG\n         PRESERVE_DOWNLOAD_DIR=true;;\n      *) show_usage; return 1;;\n    esac\n  done\n  shift $(($OPTIND-1))\n  test $# -eq 1 || { show_usage; return 1; }\n  \n  [[ -z \"$ARCH\" ]] && ARCH=$(uname -m)\n  [[ -z \"$REPO_URL\" ]] &&REPO_URL=$(get_default_repo \"$ARCH\")\n  \n  local DEST=$1\n  local REPO=$(get_core_repo_url \"$REPO_URL\" \"$ARCH\")\n  [[ -z \"$DOWNLOAD_DIR\" ]] && DOWNLOAD_DIR=$(mktemp -d)\n  mkdir -p \"$DOWNLOAD_DIR\"\n  [[ -z \"$PRESERVE_DOWNLOAD_DIR\" ]] && trap \"rm -rf '$DOWNLOAD_DIR'\" KILL TERM EXIT\n  debug \"destination directory: $DEST\"\n  debug \"core repository: $REPO\"\n  debug \"temporary directory: $DOWNLOAD_DIR\"\n  \n  # Fetch packages, install system and do a minimal configuration\n  mkdir -p \"$DEST\"\n  local LIST=$(fetch_packages_list $REPO)\n  install_pacman_packages \"${BASIC_PACKAGES[*]}\" \"$DEST\" \"$LIST\" \"$DOWNLOAD_DIR\"\n  configure_pacman \"$DEST\" \"$ARCH\"\n  configure_minimal_system \"$DEST\"\n  [[ -n \"$USE_QEMU\" ]] && configure_static_qemu \"$ARCH\" \"$DEST\"\n  install_packages \"$ARCH\" \"$DEST\" \"${BASIC_PACKAGES[*]} ${EXTRA_PACKAGES[*]}\"\n  configure_pacman \"$DEST\" \"$ARCH\" # Pacman must be re-configured\n  [[ -z \"$PRESERVE_DOWNLOAD_DIR\" ]] && rm -rf \"$DOWNLOAD_DIR\"\n  \n  debug \"Done!\"\n  debug \n  debug \"You may now chroot or arch-chroot from package arch-install-scripts:\"\n  debug \"$ sudo arch-chroot $DEST\"\n}\n\nmain \"$@\"\n"
  },
  {
    "path": "get-pacman-dependencies.sh",
    "content": "#!/bin/sh\nset -e -u -o pipefail\n\nshared_dependencies() {\n  local EXECUTABLE=$1\n  for PACKAGE in $(ldd \"$EXECUTABLE\" | grep \"=> /\" | awk '{print $3}'); do \n    LC_ALL=c pacman -Qo $PACKAGE\n  done | awk '{print $5}'\n}\n\npkgbuild_dependencies() {\n  local PKGBUILD=$1\n  local EXCLUDE=$2\n  source \"$PKGBUILD\"\n  for DEPEND in ${depends[@]}; do\n    echo \"$DEPEND\" | sed \"s/[>=<].*$//\"\n  done | grep -v \"$EXCLUDE\"\n}\n\n# Main\n{ \n  shared_dependencies \"/usr/bin/pacman\"\n  pkgbuild_dependencies \"/var/abs/core/pacman/PKGBUILD\" \"bash\"\n} | sort -u | xargs\n"
  }
]