Инструменты пользователя

Инструменты сайта


projects:temp

Это старая версия документа!


rootfs

#!/bin/bash
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
# 06_patch_img_stretch.sh — внедрение stretch_limited в initramfs и образ .img с проверками и подтверждением
 
set -euo pipefail
[[ $EUID -ne 0 ]] && exec sudo "$0" "$@"
 
MOUNT_DIR="/mnt/imgroot"
INITRD_SCRIPT="/etc/initramfs-tools/scripts/init-premount/stretch_limited"
 
# === 📁 Поиск и выбор устройств ===
mapfile -t DEVICES < <(lsblk -nrpo NAME,SIZE,MOUNTPOINT | grep -E "/dev/sd|/dev/nvme" | awk '{print $1":"$2":"$3}')
if [[ ${#DEVICES[@]} -eq 0 ]]; then
  echo "❌ Нет доступных устройств."
  exit 1
fi
 
echo "📍 Выбери куда подключён образ .img:"
i=1
for dev in "${DEVICES[@]}"; do
  IFS=":" read -r name size mnt <<< "$dev"
  status=""
  [[ -z "$mnt" ]] && status="🔌 не примонтировано"
  echo "  $i - $name ($size) $mnt $status"
  ((i++))
done
read -rp "🔀 Выбор: " choice
[[ "$choice" == "0" || -z "$choice" ]] && echo "❎ Отменено." && exit 0
 
SEL_DEV="${DEVICES[$((choice-1))]}"
IFS=":" read -r DEV_NAME DEV_SIZE DEV_MNT <<< "$SEL_DEV"
 
if [[ -z "$DEV_MNT" ]]; then
  MNT_PATH="/mnt/rpi_target0"
  mkdir -p "$MNT_PATH"
  mount "$DEV_NAME" "$MNT_PATH"
  TARGET_DIR="$MNT_PATH"
else
  TARGET_DIR="$DEV_MNT"
fi
 
# === 📂 Поиск образов ===
mapfile -t IMG_LIST < <(find "$TARGET_DIR" -maxdepth 1 -type f -name "*.img")
if [[ ${#IMG_LIST[@]} -eq 0 ]]; then
  echo "❌ Образы .img не найдены в $TARGET_DIR"
  exit 1
fi
 
echo "📂 Образы:"
i=1
for img in "${IMG_LIST[@]}"; do
  echo "  $i - $img"
  ((i++))
done
read -rp "🔀 Выбор образа: " img_choice
[[ "$img_choice" == "0" || -z "$img_choice" ]] && echo "❎ Отменено." && exit 0
 
IMGFILE="${IMG_LIST[$((img_choice-1))]}"
 
# === Запрос лимита ===
while true; do
  read -rp "📆 Укажи лимит размера rootfs в ГБ (0 = до конца диска, по умолчанию 30): " input_limit
  if [[ -z "$input_limit" ]]; then
    read -rp "🔁 Установить 30 ГБ? [Y/n] " confirm
    if [[ "$confirm" =~ ^[Nn]$ ]]; then continue; else LIMIT_GB=30; break; fi
  elif [[ "$input_limit" =~ ^[0-9]+$ ]]; then
    LIMIT_GB="$input_limit"
    break
  else
    echo "⛔ Только целые числа, пожалуйста."
  fi
done
 
# === 🔄 Подключение loop ===
LOOP_DEV=$(losetup --show -Pf "$IMGFILE")
mkdir -p "$MOUNT_DIR"
mount "${LOOP_DEV}p2" "$MOUNT_DIR"
 
# === Удаление авторасширения ===
rm -f "$MOUNT_DIR/etc/init.d/resize2fs_once"
rm -f "$MOUNT_DIR/etc/systemd/system/resize2fs_once.service"
rm -f "$MOUNT_DIR/etc/rc*.d/*resize2fs_once"
sed -i 's@ init=/usr/lib/raspi-config/init_resize.sh@@' "$MOUNT_DIR/boot/cmdline.txt"
 
# === Установка stretch_limited в initramfs ===
mkdir -p "$MOUNT_DIR/etc/initramfs-tools/scripts/init-premount"
cat <<EOF > "$MOUNT_DIR$INITRD_SCRIPT"
#!/bin/sh
PREREQ=""
prereqs() { echo "\$PREREQ"; }
case "\$1" in
  prereqs) prereqs; exit 0;;
esac
. /scripts/functions
 
FLAG_FILE="/etc/.stretch_done"
DEV="/dev/mmcblk0"
PART="\${DEV}p2"
MAX_MB=\$((LIMIT_GB * 1024))
LOGFILE="/boot/stretch_limiter.log"
log() { echo "[\$(date +%F\ %T)] \$1" >> "\$LOGFILE"; }
 
[ -f "\$FLAG_FILE" ] && log "Флаг уже есть, выход" && exit 0
 
log "📉 Минимизация rootfs (resize2fs -M)..."
resize2fs -M "\$PART" 2>>"\$LOGFILE"
 
log "📐 Ограничиваем rootfs до \$MAX_MB МБ"
START=\$(fdisk -l "\$DEV" | awk '/mmcblk0p2/ {print \$2}')
END=\$(fdisk -l "\$DEV" | awk '/mmcblk0p2/ {print \$3}')
SECTOR_SIZE=\$(blockdev --getss "\$DEV")
CURRENT_MB=\$(( (END - START + 1) * SECTOR_SIZE / 1024 / 1024 ))
 
if [ "\$CURRENT_MB" -le "\$MAX_MB" ]; then
  log "✅ Размер уже в пределах"
else
  parted -s "\$DEV" resizepart 2 "\${MAX_MB}MB"
  partprobe "\$DEV"
  sleep 1
  resize2fs "\$PART"
  log "✅ rootfs ограничен до \$MAX_MB МБ"
fi
touch "\$FLAG_FILE"
EOF
chmod +x "$MOUNT_DIR$INITRD_SCRIPT"
 
# === Монтируем окружение для chroot ===
mount --bind /dev "$MOUNT_DIR/dev"
mount --bind /sys "$MOUNT_DIR/sys"
mount --bind /proc "$MOUNT_DIR/proc"
 
# === Установка локали и initramfs ===
chroot "$MOUNT_DIR" apt-get update
chroot "$MOUNT_DIR" apt-get install -y locales initramfs-tools
chroot "$MOUNT_DIR" locale-gen en_US.UTF-8 || true
chroot "$MOUNT_DIR" update-initramfs -c -k all
 
# === Отмонтирование окружения ===
umount "$MOUNT_DIR/proc"
umount "$MOUNT_DIR/sys"
umount "$MOUNT_DIR/dev"
 
# === Обновление config.txt и initrd.img ===
sed -i '/^initramfs /d' "$MOUNT_DIR/boot/config.txt"
kver=$(chroot "$MOUNT_DIR" uname -r)
ln -sf "initrd.img-$kver" "$MOUNT_DIR/boot/initrd.img"
echo "initramfs initrd.img followkernel" >> "$MOUNT_DIR/boot/config.txt"
 
umount "$MOUNT_DIR"
losetup -d "$LOOP_DEV"
echo "✅ stretch_limited установлен в initramfs и образ. Будет выполнен при загрузке до монтирования rootfs."
projects/temp.1743609659.txt.gz · Последнее изменение: 2025/04/02 19:00 —

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution 4.0 International
CC Attribution 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki