From 025ff10990c775d795e157058f276637040e661f Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 13:51:40 -0400 Subject: [PATCH 01/12] Update ostree.sh --- ostree.sh | 243 ++++++++++++++++++++++-------------------------------- 1 file changed, 99 insertions(+), 144 deletions(-) diff --git a/ostree.sh b/ostree.sh index 0506849..42573b3 100755 --- a/ostree.sh +++ b/ostree.sh @@ -1,15 +1,19 @@ #!/usr/bin/env bash -set -o errexit # Exit on non-zero status -set -o nounset # Error on unset variables +set -o errexit # Sai imediatamente se algum comando falhar +set -o nounset # Erro se variáveis não definidas forem usadas -# [ENVIRONMENT]: OVERRIDE DEFAULTS +# ================================================================ +# [AMBIENTE]: DEFINIÇÃO DE OPÇÕES PADRÃO +# ================================================================ function ENV_CREATE_OPTS { + # Ativa impressão de comandos se não estiver em modo silencioso if [[ ${CLI_QUIET:-} != 1 ]]; then - set -o xtrace # Print executed commands while performing tasks + set -o xtrace fi + # Caso não estejamos dentro de um OSTree existente if [[ ! -d '/ostree' ]]; then - # Do not touch disks in a booted system: + # Define discos e partições declare -g OSTREE_DEV_DISK=${OSTREE_DEV_DISK:="/dev/disk/by-id/${OSTREE_DEV_SCSI}"} declare -g OSTREE_DEV_BOOT=${OSTREE_DEV_BOOT:="${OSTREE_DEV_DISK}-part1"} declare -g OSTREE_DEV_ROOT=${OSTREE_DEV_ROOT:="${OSTREE_DEV_DISK}-part2"} @@ -17,6 +21,7 @@ function ENV_CREATE_OPTS { declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/tmp/chroot'} fi + # Variáveis globais do sistema declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/'} declare -g OSTREE_SYS_TREE=${OSTREE_SYS_TREE:='/tmp/rootfs'} declare -g OSTREE_SYS_KARG=${OSTREE_SYS_KARG:=''} @@ -26,37 +31,43 @@ function ENV_CREATE_OPTS { declare -g OSTREE_OPT_NOMERGE=${OSTREE_OPT_NOMERGE='--no-merge'} declare -g OSTREE_REP_NAME=${OSTREE_REP_NAME:='archlinux'} + # Ajusta fuso horário se definido if [[ -n ${SYSTEM_OPT_TIMEZONE:-} ]]; then - # Do not modify host's time unless explicitly specified timedatectl set-timezone ${SYSTEM_OPT_TIMEZONE} timedatectl set-ntp 1 fi declare -g SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE:='Etc/UTC'} declare -g SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP:='us'} + # Configuração dos arquivos de build do Podman declare -g PODMAN_OPT_BUILDFILE=${PODMAN_OPT_BUILDFILE:="${0%/*}/archlinux/Containerfile.base:ostree/base","${0%/*}/Containerfile.host.example:ostree/host"} declare -g PODMAN_OPT_NOCACHE=${PODMAN_OPT_NOCACHE:='0'} declare -g PACMAN_OPT_NOCACHE=${PACMAN_OPT_NOCACHE:='0'} } - -# [ENVIRONMENT]: OSTREE CHECK +# ================================================================ +# [AMBIENTE]: VERIFICAÇÃO DE OSTREE LOCAL +# ================================================================ function ENV_VERIFY_LOCAL { if [[ ! -d '/ostree' ]]; then - printf >&2 '\e[31m%s\e[0m\n' 'OSTree could not be found in: /ostree' + printf >&2 '\e[31m%s\e[0m\n' 'OSTree não encontrado em: /ostree' return 1 fi } -# [ENVIRONMENT]: BUILD DEPENDENCIES +# ================================================================ +# [AMBIENTE]: INSTALA DEPENDÊNCIAS NECESSÁRIAS +# ================================================================ function ENV_CREATE_DEPS { - # Skip in OSTree as filesystem is read-only + # Ignora caso o sistema seja read-only OSTree if ! ENV_VERIFY_LOCAL 2>/dev/null; then pacman --noconfirm --sync --needed $@ fi } -# [DISK]: PARTITIONING (GPT+UEFI) +# ================================================================ +# [DISCO]: PARTICIONAMENTO (GPT + UEFI) +# ================================================================ function DISK_CREATE_LAYOUT { ENV_CREATE_DEPS parted mkdir -p ${OSTREE_SYS_ROOT} @@ -69,7 +80,9 @@ function DISK_CREATE_LAYOUT { mkpart ${OSTREE_SYS_HOME_LABEL} xfs 25GiB 100% } -# [DISK]: FILESYSTEM (ESP+XFS) +# ================================================================ +# [DISCO]: FORMATAÇÃO DE PARTIÇÕES +# ================================================================ function DISK_CREATE_FORMAT { ENV_CREATE_DEPS dosfstools xfsprogs mkfs.vfat -n ${OSTREE_SYS_BOOT_LABEL} -F 32 ${OSTREE_DEV_BOOT} @@ -77,13 +90,17 @@ function DISK_CREATE_FORMAT { mkfs.xfs -L ${OSTREE_SYS_HOME_LABEL} -f ${OSTREE_DEV_HOME} -n ftype=1 } -# [DISK]: BUILD DIRECTORY +# ================================================================ +# [DISCO]: MONTAGEM DAS PARTIÇÕES +# ================================================================ function DISK_CREATE_MOUNTS { mount --mkdir ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} mount --mkdir ${OSTREE_DEV_BOOT} ${OSTREE_SYS_ROOT}/boot/efi } -# [OSTREE]: FIRST INITIALIZATION +# ================================================================ +# [OSTREE]: INICIALIZAÇÃO DO REPOSITÓRIO +# ================================================================ function OSTREE_CREATE_REPO { ENV_CREATE_DEPS ostree which ostree admin init-fs --sysroot="${OSTREE_SYS_ROOT}" --modern ${OSTREE_SYS_ROOT} @@ -92,9 +109,11 @@ function OSTREE_CREATE_REPO { ostree config --repo="${OSTREE_SYS_ROOT}/ostree/repo" set sysroot.bootprefix 1 } -# [OSTREE]: BUILD ROOTFS +# ================================================================ +# [OSTREE]: CRIAÇÃO DO ROOTFS +# ================================================================ function OSTREE_CREATE_ROOTFS { - # Add support for overlay storage driver in LiveCD + # Suporte para overlay em LiveCD if [[ $(df --output=fstype / | tail --lines 1) = 'overlay' ]]; then ENV_CREATE_DEPS fuse-overlayfs declare -x TMPDIR='/tmp/podman' @@ -104,10 +123,9 @@ function OSTREE_CREATE_ROOTFS { ) fi - # Install Podman ENV_CREATE_DEPS podman - # Copy Pacman package cache into /var by default (to avoid duplication) + # Reaproveita cache do pacman if [[ ${PACMAN_OPT_NOCACHE} == 0 ]]; then mkdir -p "${TMPDIR:-}/var/cache/pacman" local PODMAN_OPT_BUILD=( @@ -115,7 +133,6 @@ function OSTREE_CREATE_ROOTFS { ) fi - # Skip Podman layer cache if requested if [[ ${PODMAN_OPT_NOCACHE} == 1 ]]; then local PODMAN_OPT_BUILD=( ${PODMAN_OPT_BUILD[@]} @@ -123,7 +140,7 @@ function OSTREE_CREATE_ROOTFS { ) fi - # Podman: create rootfs from multiple Containerfiles + # Criação do rootfs via Podman build for TARGET in ${PODMAN_OPT_BUILDFILE//,/ }; do local PODMAN_OPT_IMG=(${TARGET%:*}) local PODMAN_OPT_TAG=(${TARGET#*:}) @@ -140,86 +157,67 @@ function OSTREE_CREATE_ROOTFS { --pull='newer' done - # Ostreeify: retrieve rootfs (workaround: `podman build --output local` doesn't preserve ownership) + # Exporta rootfs rm -rf ${OSTREE_SYS_TREE} mkdir -p ${OSTREE_SYS_TREE} podman ${PODMAN_OPT_GLOBAL[@]} export $(podman ${PODMAN_OPT_GLOBAL[@]} create ${PODMAN_OPT_TAG} bash) | tar -xC ${OSTREE_SYS_TREE} } -# [OSTREE]: DIRECTORY STRUCTURE (https://ostree.readthedocs.io/en/stable/manual/adapting-existing) +# ================================================================ +# [OSTREE]: ORGANIZAÇÃO DE DIRETÓRIOS +# ================================================================ function OSTREE_CREATE_LAYOUT { - # Doing it here allows the container to be runnable/debuggable and Containerfile reusable mv ${OSTREE_SYS_TREE}/etc ${OSTREE_SYS_TREE}/usr/ - rm -r ${OSTREE_SYS_TREE}/home ln -s var/home ${OSTREE_SYS_TREE}/home - rm -r ${OSTREE_SYS_TREE}/mnt ln -s var/mnt ${OSTREE_SYS_TREE}/mnt - rm -r ${OSTREE_SYS_TREE}/opt ln -s var/opt ${OSTREE_SYS_TREE}/opt - rm -r ${OSTREE_SYS_TREE}/root ln -s var/roothome ${OSTREE_SYS_TREE}/root - rm -r ${OSTREE_SYS_TREE}/srv ln -s var/srv ${OSTREE_SYS_TREE}/srv - mkdir ${OSTREE_SYS_TREE}/sysroot ln -s sysroot/ostree ${OSTREE_SYS_TREE}/ostree - rm -r ${OSTREE_SYS_TREE}/usr/local ln -s ../var/usrlocal ${OSTREE_SYS_TREE}/usr/local - printf >&1 '%s\n' 'Creating tmpfiles' - echo 'd /var/home 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/log/journal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/mnt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/opt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/roothome 0700 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/srv 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/bin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/etc 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/games 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/include 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/man 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/sbin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/share 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/src 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /run/media 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - - # Only retain information about Pacman packages in new rootfs + # Criação de tmpfiles + printf >&1 '%s\n' 'Criando tmpfiles' + for dir in home lib log/journal mnt opt roothome srv usrlocal usrlocal/bin usrlocal/etc usrlocal/games usrlocal/include usrlocal/lib usrlocal/man usrlocal/sbin usrlocal/share usrlocal/src run/media; do + echo "d /var/${dir} 0755 root root -" >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + done + echo "d /var/roothome 0700 root root -" >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + + # Pacman no novo rootfs mv ${OSTREE_SYS_TREE}/var/lib/pacman ${OSTREE_SYS_TREE}/usr/lib/ - sed -i \ - -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ - -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ - ${OSTREE_SYS_TREE}/usr/etc/pacman.conf + sed -i -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ + -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ + ${OSTREE_SYS_TREE}/usr/etc/pacman.conf - # Allow Pacman to store update notice id during unlock mode mkdir ${OSTREE_SYS_TREE}/usr/lib/pacmanlocal - - # OSTree mounts /ostree/deploy/${OSTREE_REP_NAME}/var to /var rm -r ${OSTREE_SYS_TREE}/var/* } -# [OSTREE]: CREATE COMMIT +# ================================================================ +# [OSTREE]: CRIA COMMIT E DEPLOY +# ================================================================ function OSTREE_DEPLOY_IMAGE { - # Update repository and boot entries in GRUB2 ostree commit --repo="${OSTREE_SYS_ROOT}/ostree/repo" --branch="${OSTREE_REP_NAME}/latest" --tree=dir="${OSTREE_SYS_TREE}" ostree admin deploy --sysroot="${OSTREE_SYS_ROOT}" --karg="root=LABEL=${OSTREE_SYS_ROOT_LABEL} rw ${OSTREE_SYS_KARG}" --os="${OSTREE_REP_NAME}" ${OSTREE_OPT_NOMERGE} --retain ${OSTREE_REP_NAME}/latest } -# [OSTREE]: UNDO COMMIT +# ================================================================ +# [OSTREE]: REVERT DEPLOY +# ================================================================ function OSTREE_REVERT_IMAGE { ostree admin undeploy --sysroot="${OSTREE_SYS_ROOT}" 0 } -# [BOOTLOADER]: FIRST BOOT -# | Todo: improve grub-mkconfig +# ================================================================ +# [BOOTLOADER]: INSTALAÇÃO INICIAL +# ================================================================ function BOOTLOADER_CREATE { grub-install --target='x86_64-efi' --efi-directory="${OSTREE_SYS_ROOT}/boot/efi" --boot-directory="${OSTREE_SYS_ROOT}/boot/efi/EFI" --bootloader-id="${OSTREE_REP_NAME}" --removable ${OSTREE_DEV_BOOT} @@ -235,7 +233,9 @@ function BOOTLOADER_CREATE { umount --recursive ${OSTREE_SYS_ROOT} } -# [CLI]: TASK FINECONTROL +# ================================================================ +# [CLI]: TRATAMENTO DE ARGUMENTOS +# ================================================================ function CLI_SETUP { CLI_ARGS=$(getopt \ --alternative \ @@ -245,144 +245,99 @@ function CLI_SETUP { -- "${@}" ) - # Rewrite "${@}" eval set -- "${CLI_ARGS}" - # Arguments while [[ ${#} > 0 ]]; do CLI_ARG=${1:-} CLI_VAL=${2:-} - # Options case ${CLI_ARG} in - '-b' | '--base-os') - declare -g OSTREE_REP_NAME=${CLI_VAL} - ;; - - '-c' | '--cmdline') - declare -g OSTREE_SYS_KARG=${CLI_VAL} - ;; - - '-d' | '--dev') - declare -g OSTREE_DEV_SCSI=${CLI_VAL} - ;; - - '-f' | '--file') - declare -g PODMAN_OPT_BUILDFILE=${CLI_VAL} - ;; - - '-k' | '--keymap') - declare -g SYSTEM_OPT_KEYMAP=${CLI_VAL} - ;; - - '-t' | '--time') - declare -g SYSTEM_OPT_TIMEZONE=${CLI_VAL} - ;; + '-b' | '--base-os') declare -g OSTREE_REP_NAME=${CLI_VAL} ;; + '-c' | '--cmdline') declare -g OSTREE_SYS_KARG=${CLI_VAL} ;; + '-d' | '--dev') declare -g OSTREE_DEV_SCSI=${CLI_VAL} ;; + '-f' | '--file') declare -g PODMAN_OPT_BUILDFILE=${CLI_VAL} ;; + '-k' | '--keymap') declare -g SYSTEM_OPT_KEYMAP=${CLI_VAL} ;; + '-t' | '--time') declare -g SYSTEM_OPT_TIMEZONE=${CLI_VAL} ;; esac - # Switches [[ ${CLI_VAL@L} == 'true' ]] && CLI_VAL='1' [[ ${CLI_VAL@L} == 'false' ]] && CLI_VAL='0' + case ${CLI_ARG} in - '-m' | '--merge') - declare -g OSTREE_OPT_NOMERGE=${CLI_VAL:-} - ;; - - '-n' | '--no-cache') - declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} - declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '--no-pacman-cache') - declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '--no-podman-cache') - declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '-q' | '--quiet') - declare -g CLI_QUIET=${CLI_VAL:-1} - ;; + '-m' | '--merge') declare -g OSTREE_OPT_NOMERGE=${CLI_VAL:-} ;; + '-n' | '--no-cache') declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1}; declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; + '--no-pacman-cache') declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; + '--no-podman-cache') declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; + '-q' | '--quiet') declare -g CLI_QUIET=${CLI_VAL:-1} ;; esac - # Commands if [[ ${CLI_ARG} == '--' ]]; then case ${CLI_VAL} in 'install') ENV_CREATE_OPTS - DISK_CREATE_LAYOUT DISK_CREATE_FORMAT DISK_CREATE_MOUNTS - OSTREE_CREATE_REPO OSTREE_CREATE_ROOTFS OSTREE_CREATE_LAYOUT OSTREE_DEPLOY_IMAGE - BOOTLOADER_CREATE ;; - 'upgrade') ENV_VERIFY_LOCAL || exit $? ENV_CREATE_OPTS - OSTREE_CREATE_ROOTFS OSTREE_CREATE_LAYOUT OSTREE_DEPLOY_IMAGE ;; - 'revert') ENV_VERIFY_LOCAL || exit $? ENV_CREATE_OPTS - OSTREE_REVERT_IMAGE ;; - *) if [[ $(type -t ${CLI_VAL}) == 'function' ]]; then ENV_CREATE_OPTS ${CLI_VAL} fi ;;& - * | 'help') local USAGE=( - 'Usage:' - " ${0##*/} [options]" - 'Commands:' - ' install : (Create deployment) : Partitions, formats and initializes a new OSTree repository' - ' upgrade : (Update deployment) : Creates a new OSTree commit' - ' revert : (Update deployment) : Rolls back version 0' - 'Options:' - ' -b, --base-os string : (install/upgrade) : Name of OS to use as a base. Defaults to archlinux' - ' -c, --cmdline string : (install/upgrade) : List of kernel arguments for boot' - ' -d, --dev string : (install ) : Device SCSI (ID-LINK) for new installation' - ' -f, --file stringArray : (install/upgrade) : Containerfile(s) for new deployment' - ' -k, --keymap string : (install/upgrade) : TTY keyboard layout for new deployment' - ' -t, --time string : (install/upgrade) : Update host timezone for new deployment' + 'Uso:' + " ${0##*/} [opções]" + 'Comandos:' + ' install : Cria deploy completo (partições, rootfs, OSTree, GRUB)' + ' upgrade : Atualiza deployment criando novo commit' + ' revert : Reverte para commit anterior' + 'Opções:' + ' -b, --base-os string : Nome da OS base (default archlinux)' + ' -c, --cmdline string : Argumentos do kernel para boot' + ' -d, --dev string : Device SCSI para instalação' + ' -f, --file stringArray : Containerfile(s) para novo deploy' + ' -k, --keymap string : Layout do teclado TTY' + ' -t, --time string : Fuso horário' 'Switches:' - ' -m, --merge : ( upgrade) : Retain contents of /etc for existing deployment' - ' -n, --no-cache : (install/upgrade) : Skip any cached data (note: implied for first deployment)' - ' --no-pacman-cache : (install/upgrade) : Skip Pacman package cache' - ' --no-podman-cache : (install/upgrade) : Skip Podman layer cache' - ' -q, --quiet : (install/upgrade) : Reduce verbosity' + ' -m, --merge : Mantém /etc existente' + ' -n, --no-cache : Ignora cache' + ' --no-pacman-cache : Ignora cache do Pacman' + ' --no-podman-cache : Ignora cache do Podman' + ' -q, --quiet : Reduz verbosidade' ) printf >&1 '%s\n' "${USAGE[@]}" - if [[ ${CLI_VAL} != 'help' && -n ${CLI_VAL} ]]; then - printf >&2 '\n%s\n' "${0##*/}: unrecognized command '${CLI_VAL}'" + printf >&2 '\n%s\n' "${0##*/}: comando não reconhecido '${CLI_VAL}'" exit 127 fi ;; esac break fi - - # Continue to the next argument shift 2 done } +# ================================================================ +# EXECUTA CLI +# ================================================================ CLI_SETUP "${@}" From e26c08f576c8525a75e79a74375a3725aa2ca14f Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 14:05:42 -0400 Subject: [PATCH 02/12] Update ostree.sh --- ostree.sh | 468 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 247 insertions(+), 221 deletions(-) diff --git a/ostree.sh b/ostree.sh index 42573b3..b580f01 100755 --- a/ostree.sh +++ b/ostree.sh @@ -1,242 +1,270 @@ #!/usr/bin/env bash -set -o errexit # Sai imediatamente se algum comando falhar -set -o nounset # Erro se variáveis não definidas forem usadas +set -o errexit # Sai se houver erro +set -o nounset # Erro se usar variável não definida -# ================================================================ +# ======================================================== # [AMBIENTE]: DEFINIÇÃO DE OPÇÕES PADRÃO -# ================================================================ -function ENV_CREATE_OPTS { - # Ativa impressão de comandos se não estiver em modo silencioso - if [[ ${CLI_QUIET:-} != 1 ]]; then - set -o xtrace +# ======================================================== +function AMBIENTE_DEFINIR_OPCOES { + if [[ ${CLI_SILENCIOSO:-} != 1 ]]; then + set -o xtrace # Mostra os comandos sendo executados fi - # Caso não estejamos dentro de um OSTree existente if [[ ! -d '/ostree' ]]; then - # Define discos e partições - declare -g OSTREE_DEV_DISK=${OSTREE_DEV_DISK:="/dev/disk/by-id/${OSTREE_DEV_SCSI}"} - declare -g OSTREE_DEV_BOOT=${OSTREE_DEV_BOOT:="${OSTREE_DEV_DISK}-part1"} - declare -g OSTREE_DEV_ROOT=${OSTREE_DEV_ROOT:="${OSTREE_DEV_DISK}-part2"} - declare -g OSTREE_DEV_HOME=${OSTREE_DEV_HOME:="${OSTREE_DEV_DISK}-part3"} - declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/tmp/chroot'} + # Não mexer nos discos se o sistema já estiver iniciado + declare -g DISCO_DESTINO=${DISCO_DESTINO:="/dev/disk/by-id/${DISCO_SCSI}"} + declare -g PARTICAO_BOOT=${PARTICAO_BOOT:="${DISCO_DESTINO}-part1"} + declare -g PARTICAO_ROOT=${PARTICAO_ROOT:="${DISCO_DESTINO}-part2"} + declare -g MONTAGEM_TEMP=${MONTAGEM_TEMP:='/tmp/chroot'} fi - # Variáveis globais do sistema - declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/'} - declare -g OSTREE_SYS_TREE=${OSTREE_SYS_TREE:='/tmp/rootfs'} - declare -g OSTREE_SYS_KARG=${OSTREE_SYS_KARG:=''} - declare -g OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL:='SYS_BOOT'} - declare -g OSTREE_SYS_ROOT_LABEL=${OSTREE_SYS_ROOT_LABEL:='SYS_ROOT'} - declare -g OSTREE_SYS_HOME_LABEL=${OSTREE_SYS_HOME_LABEL:='SYS_HOME'} - declare -g OSTREE_OPT_NOMERGE=${OSTREE_OPT_NOMERGE='--no-merge'} - declare -g OSTREE_REP_NAME=${OSTREE_REP_NAME:='archlinux'} - - # Ajusta fuso horário se definido - if [[ -n ${SYSTEM_OPT_TIMEZONE:-} ]]; then - timedatectl set-timezone ${SYSTEM_OPT_TIMEZONE} + declare -g MONTAGEM_TEMP=${MONTAGEM_TEMP:='/'} + declare -g ROOTFS_TEMP=${ROOTFS_TEMP:='/tmp/rootfs'} + declare -g ARG_KERNEL=${ARG_KERNEL:='rootflags=subvol=@ rootfstype=btrfs'} + declare -g LABEL_BOOT=${LABEL_BOOT:='SYS_BOOT'} + declare -g LABEL_ROOT=${LABEL_ROOT:='SYS_ROOT'} + declare -g OPT_NOMERGE=${OPT_NOMERGE='--no-merge'} + declare -g REPO_NOME=${REPO_NOME:='raglinux'} + + if [[ -n ${FUSO_HORARIO:-} ]]; then + timedatectl set-timezone ${FUSO_HORARIO} timedatectl set-ntp 1 fi - declare -g SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE:='Etc/UTC'} - declare -g SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP:='us'} + declare -g FUSO_HORARIO=${FUSO_HORARIO:='America/Sao_Paulo'} + declare -g TECLADO=${TECLADO:='br-abnt2'} - # Configuração dos arquivos de build do Podman - declare -g PODMAN_OPT_BUILDFILE=${PODMAN_OPT_BUILDFILE:="${0%/*}/archlinux/Containerfile.base:ostree/base","${0%/*}/Containerfile.host.example:ostree/host"} - declare -g PODMAN_OPT_NOCACHE=${PODMAN_OPT_NOCACHE:='0'} - declare -g PACMAN_OPT_NOCACHE=${PACMAN_OPT_NOCACHE:='0'} + declare -g ARQUIVO_CONTAINER=${ARQUIVO_CONTAINER:="${0%/*}/Containerfile.raglinux:ostree/base"} + declare -g SEM_CACHE_PODMAN=${SEM_CACHE_PODMAN:='0'} + declare -g SEM_CACHE_PACMAN=${SEM_CACHE_PACMAN:='0'} } -# ================================================================ -# [AMBIENTE]: VERIFICAÇÃO DE OSTREE LOCAL -# ================================================================ -function ENV_VERIFY_LOCAL { +# ======================================================== +# [AMBIENTE]: VERIFICA OSTREE LOCAL +# ======================================================== +function AMBIENTE_VERIFICAR { if [[ ! -d '/ostree' ]]; then printf >&2 '\e[31m%s\e[0m\n' 'OSTree não encontrado em: /ostree' return 1 fi } -# ================================================================ -# [AMBIENTE]: INSTALA DEPENDÊNCIAS NECESSÁRIAS -# ================================================================ -function ENV_CREATE_DEPS { - # Ignora caso o sistema seja read-only OSTree - if ! ENV_VERIFY_LOCAL 2>/dev/null; then - pacman --noconfirm --sync --needed $@ +# ======================================================== +# [AMBIENTE]: INSTALAR DEPENDÊNCIAS +# ======================================================== +function AMBIENTE_INSTALAR_DEPENDENCIAS { + # Ignora em OSTree (filesystem read-only) + if ! AMBIENTE_VERIFICAR 2>/dev/null; then + pacman --noconfirm --sync --needed "$@" fi } -# ================================================================ -# [DISCO]: PARTICIONAMENTO (GPT + UEFI) -# ================================================================ -function DISK_CREATE_LAYOUT { - ENV_CREATE_DEPS parted - mkdir -p ${OSTREE_SYS_ROOT} - lsblk --noheadings --output='MOUNTPOINTS' | grep -w ${OSTREE_SYS_ROOT} | xargs -r umount --lazy --verbose - parted -a optimal -s ${OSTREE_DEV_DISK} -- \ +# ======================================================== +# [DISCO]: CRIAR PARTIÇÕES GPT+UEFI +# ======================================================== +function DISCO_CRIAR_LAYOUT { + AMBIENTE_INSTALAR_DEPENDENCIAS parted + mkdir -p ${MONTAGEM_TEMP} + lsblk --noheadings --output='MOUNTPOINTS' | grep -w ${MONTAGEM_TEMP} | xargs -r umount --lazy --verbose + + if [[ -b "${PARTICAO_BOOT}" && -b "${PARTICAO_ROOT}" ]]; then + echo "Partições já existem, pulando criação..." + return 0 + fi + + parted -a optimal -s ${DISCO_DESTINO} -- \ mklabel gpt \ - mkpart ${OSTREE_SYS_BOOT_LABEL} fat32 0% 257MiB \ + mkpart ${LABEL_BOOT} fat32 0% 257MiB \ set 1 esp on \ - mkpart ${OSTREE_SYS_ROOT_LABEL} xfs 257MiB 25GiB \ - mkpart ${OSTREE_SYS_HOME_LABEL} xfs 25GiB 100% + mkpart ${LABEL_ROOT} btrfs 257MiB 100% } -# ================================================================ -# [DISCO]: FORMATAÇÃO DE PARTIÇÕES -# ================================================================ -function DISK_CREATE_FORMAT { - ENV_CREATE_DEPS dosfstools xfsprogs - mkfs.vfat -n ${OSTREE_SYS_BOOT_LABEL} -F 32 ${OSTREE_DEV_BOOT} - mkfs.xfs -L ${OSTREE_SYS_ROOT_LABEL} -f ${OSTREE_DEV_ROOT} -n ftype=1 - mkfs.xfs -L ${OSTREE_SYS_HOME_LABEL} -f ${OSTREE_DEV_HOME} -n ftype=1 +# ======================================================== +# [DISCO]: FORMATAR PARTIÇÕES +# ======================================================== +function DISCO_FORMATAR { + AMBIENTE_INSTALAR_DEPENDENCIAS dosfstools btrfs-progs + mkfs.vfat -n ${LABEL_BOOT} -F 32 ${PARTICAO_BOOT} + mkfs.btrfs -L ${LABEL_ROOT} -f ${PARTICAO_ROOT} } -# ================================================================ -# [DISCO]: MONTAGEM DAS PARTIÇÕES -# ================================================================ -function DISK_CREATE_MOUNTS { - mount --mkdir ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} - mount --mkdir ${OSTREE_DEV_BOOT} ${OSTREE_SYS_ROOT}/boot/efi +# ======================================================== +# [DISCO]: MONTAR E CRIAR SUBVOLUMES +# ======================================================== +function DISCO_MONTAR { + mount ${PARTICAO_ROOT} ${MONTAGEM_TEMP} + + btrfs subvolume create ${MONTAGEM_TEMP}/@ + btrfs subvolume create ${MONTAGEM_TEMP}/@home + btrfs subvolume create ${MONTAGEM_TEMP}/@var + btrfs subvolume create ${MONTAGEM_TEMP}/@ostree + + umount ${MONTAGEM_TEMP} + mount -o subvol=@ ${PARTICAO_ROOT} ${MONTAGEM_TEMP} + + mkdir -p ${MONTAGEM_TEMP}/{home,var,ostree} + mount -o subvol=@home ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/home + mount -o subvol=@var ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/var + mount -o subvol=@ostree ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/ostree + + mount --mkdir ${PARTICAO_BOOT} ${MONTAGEM_TEMP}/boot/efi } -# ================================================================ +# ======================================================== # [OSTREE]: INICIALIZAÇÃO DO REPOSITÓRIO -# ================================================================ -function OSTREE_CREATE_REPO { - ENV_CREATE_DEPS ostree which - ostree admin init-fs --sysroot="${OSTREE_SYS_ROOT}" --modern ${OSTREE_SYS_ROOT} - ostree admin stateroot-init --sysroot="${OSTREE_SYS_ROOT}" ${OSTREE_REP_NAME} - ostree init --repo="${OSTREE_SYS_ROOT}/ostree/repo" --mode='bare' - ostree config --repo="${OSTREE_SYS_ROOT}/ostree/repo" set sysroot.bootprefix 1 +# ======================================================== +function OSTREE_CRIA_REPO { + AMBIENTE_INSTALAR_DEPENDENCIAS ostree which + ostree admin init-fs --sysroot="${MONTAGEM_TEMP}" --modern ${MONTAGEM_TEMP} + ostree admin stateroot-init --sysroot="${MONTAGEM_TEMP}" ${REPO_NOME} + ostree init --repo="${MONTAGEM_TEMP}/ostree/repo" --mode='bare' + ostree config --repo="${MONTAGEM_TEMP}/ostree/repo" set sysroot.bootprefix 1 } -# ================================================================ -# [OSTREE]: CRIAÇÃO DO ROOTFS -# ================================================================ -function OSTREE_CREATE_ROOTFS { - # Suporte para overlay em LiveCD +# ======================================================== +# [OSTREE]: CRIAR ROOTFS COM PODMAN +# ======================================================== +function OSTREE_CRIA_ROOTFS { if [[ $(df --output=fstype / | tail --lines 1) = 'overlay' ]]; then - ENV_CREATE_DEPS fuse-overlayfs + AMBIENTE_INSTALAR_DEPENDENCIAS fuse-overlayfs declare -x TMPDIR='/tmp/podman' - local PODMAN_OPT_GLOBAL=( + local OPT_PODMAN_GLOBAL=( --root="${TMPDIR}/storage" --tmpdir="${TMPDIR}/tmp" ) fi - ENV_CREATE_DEPS podman + AMBIENTE_INSTALAR_DEPENDENCIAS podman - # Reaproveita cache do pacman - if [[ ${PACMAN_OPT_NOCACHE} == 0 ]]; then + if [[ ${SEM_CACHE_PACMAN} == 0 ]]; then mkdir -p "${TMPDIR:-}/var/cache/pacman" - local PODMAN_OPT_BUILD=( + local OPT_PODMAN_BUILD=( --volume="${TMPDIR:-}/var/cache/pacman:${TMPDIR:-}/var/cache/pacman" ) fi - if [[ ${PODMAN_OPT_NOCACHE} == 1 ]]; then - local PODMAN_OPT_BUILD=( - ${PODMAN_OPT_BUILD[@]} + if [[ ${SEM_CACHE_PODMAN} == 1 ]]; then + local OPT_PODMAN_BUILD=( + ${OPT_PODMAN_BUILD[@]} --no-cache='1' ) fi - # Criação do rootfs via Podman build - for TARGET in ${PODMAN_OPT_BUILDFILE//,/ }; do - local PODMAN_OPT_IMG=(${TARGET%:*}) - local PODMAN_OPT_TAG=(${TARGET#*:}) - podman ${PODMAN_OPT_GLOBAL[@]} build \ - ${PODMAN_OPT_BUILD[@]} \ - --file="${PODMAN_OPT_IMG}" \ - --tag="${PODMAN_OPT_TAG}" \ + for TARGET in ${ARQUIVO_CONTAINER//,/ }; do + local IMG=${TARGET%:*} + local TAG=${TARGET#*:} + podman ${OPT_PODMAN_GLOBAL[@]} build \ + ${OPT_PODMAN_BUILD[@]} \ + --file="${IMG}" \ + --tag="${TAG}" \ --cap-add='SYS_ADMIN' \ - --build-arg="OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL}" \ - --build-arg="OSTREE_SYS_HOME_LABEL=${OSTREE_SYS_HOME_LABEL}" \ - --build-arg="OSTREE_SYS_ROOT_LABEL=${OSTREE_SYS_ROOT_LABEL}" \ - --build-arg="SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE}" \ - --build-arg="SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP}" \ + --build-arg="LABEL_BOOT=${LABEL_BOOT}" \ + --build-arg="LABEL_ROOT=${LABEL_ROOT}" \ + --build-arg="FUSO_HORARIO=${FUSO_HORARIO}" \ + --build-arg="TECLADO=${TECLADO}" \ --pull='newer' done - # Exporta rootfs - rm -rf ${OSTREE_SYS_TREE} - mkdir -p ${OSTREE_SYS_TREE} - podman ${PODMAN_OPT_GLOBAL[@]} export $(podman ${PODMAN_OPT_GLOBAL[@]} create ${PODMAN_OPT_TAG} bash) | tar -xC ${OSTREE_SYS_TREE} + rm -rf ${ROOTFS_TEMP} + mkdir -p ${ROOTFS_TEMP} + podman ${OPT_PODMAN_GLOBAL[@]} export $(podman ${OPT_PODMAN_GLOBAL[@]} create ${TAG} bash) | tar -xC ${ROOTFS_TEMP} } -# ================================================================ -# [OSTREE]: ORGANIZAÇÃO DE DIRETÓRIOS -# ================================================================ -function OSTREE_CREATE_LAYOUT { - mv ${OSTREE_SYS_TREE}/etc ${OSTREE_SYS_TREE}/usr/ - rm -r ${OSTREE_SYS_TREE}/home - ln -s var/home ${OSTREE_SYS_TREE}/home - rm -r ${OSTREE_SYS_TREE}/mnt - ln -s var/mnt ${OSTREE_SYS_TREE}/mnt - rm -r ${OSTREE_SYS_TREE}/opt - ln -s var/opt ${OSTREE_SYS_TREE}/opt - rm -r ${OSTREE_SYS_TREE}/root - ln -s var/roothome ${OSTREE_SYS_TREE}/root - rm -r ${OSTREE_SYS_TREE}/srv - ln -s var/srv ${OSTREE_SYS_TREE}/srv - mkdir ${OSTREE_SYS_TREE}/sysroot - ln -s sysroot/ostree ${OSTREE_SYS_TREE}/ostree - rm -r ${OSTREE_SYS_TREE}/usr/local - ln -s ../var/usrlocal ${OSTREE_SYS_TREE}/usr/local - - # Criação de tmpfiles - printf >&1 '%s\n' 'Criando tmpfiles' - for dir in home lib log/journal mnt opt roothome srv usrlocal usrlocal/bin usrlocal/etc usrlocal/games usrlocal/include usrlocal/lib usrlocal/man usrlocal/sbin usrlocal/share usrlocal/src run/media; do - echo "d /var/${dir} 0755 root root -" >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - done - echo "d /var/roothome 0700 root root -" >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf +# ======================================================== +# [OSTREE]: AJUSTAR ESTRUTURA DE DIRETÓRIOS +# ======================================================== +function OSTREE_AJUSTAR_LAYOUT { + mv ${ROOTFS_TEMP}/etc ${ROOTFS_TEMP}/usr/ + + rm -r ${ROOTFS_TEMP}/home + ln -s var/home ${ROOTFS_TEMP}/home - # Pacman no novo rootfs - mv ${OSTREE_SYS_TREE}/var/lib/pacman ${OSTREE_SYS_TREE}/usr/lib/ - sed -i -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ - -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ - ${OSTREE_SYS_TREE}/usr/etc/pacman.conf + rm -r ${ROOTFS_TEMP}/mnt + ln -s var/mnt ${ROOTFS_TEMP}/mnt - mkdir ${OSTREE_SYS_TREE}/usr/lib/pacmanlocal - rm -r ${OSTREE_SYS_TREE}/var/* + rm -r ${ROOTFS_TEMP}/opt + ln -s var/opt ${ROOTFS_TEMP}/opt + + rm -r ${ROOTFS_TEMP}/root + ln -s var/roothome ${ROOTFS_TEMP}/root + + rm -r ${ROOTFS_TEMP}/srv + ln -s var/srv ${ROOTFS_TEMP}/srv + + mkdir ${ROOTFS_TEMP}/sysroot + ln -s sysroot/ostree ${ROOTFS_TEMP}/ostree + + rm -r ${ROOTFS_TEMP}/usr/local + ln -s ../var/usrlocal ${ROOTFS_TEMP}/usr/local + + printf >&1 '%s\n' 'Criando tmpfiles' + cat <> ${ROOTFS_TEMP}/usr/lib/tmpfiles.d/ostree-0-integracao.conf +d /var/home 0755 root root - +d /var/lib 0755 root root - +d /var/log/journal 0755 root root - +d /var/mnt 0755 root root - +d /var/opt 0755 root root - +d /var/roothome 0700 root root - +d /var/srv 0755 root root - +d /var/usrlocal 0755 root root - +d /var/usrlocal/bin 0755 root root - +d /var/usrlocal/etc 0755 root root - +d /var/usrlocal/games 0755 root root - +d /var/usrlocal/include 0755 root root - +d /var/usrlocal/lib 0755 root root - +d /var/usrlocal/man 0755 root root - +d /var/usrlocal/sbin 0755 root root - +d /var/usrlocal/share 0755 root root - +d /var/usrlocal/src 0755 root root - +d /run/media 0755 root root - +EOF + + mv ${ROOTFS_TEMP}/var/lib/pacman ${ROOTFS_TEMP}/usr/lib/ + sed -i \ + -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ + -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ + ${ROOTFS_TEMP}/usr/etc/pacman.conf + + mkdir ${ROOTFS_TEMP}/usr/lib/pacmanlocal + rm -r ${ROOTFS_TEMP}/var/* } -# ================================================================ -# [OSTREE]: CRIA COMMIT E DEPLOY -# ================================================================ -function OSTREE_DEPLOY_IMAGE { - ostree commit --repo="${OSTREE_SYS_ROOT}/ostree/repo" --branch="${OSTREE_REP_NAME}/latest" --tree=dir="${OSTREE_SYS_TREE}" - ostree admin deploy --sysroot="${OSTREE_SYS_ROOT}" --karg="root=LABEL=${OSTREE_SYS_ROOT_LABEL} rw ${OSTREE_SYS_KARG}" --os="${OSTREE_REP_NAME}" ${OSTREE_OPT_NOMERGE} --retain ${OSTREE_REP_NAME}/latest +# ======================================================== +# [OSTREE]: CRIAR COMMIT +# ======================================================== +function OSTREE_DEPLOY { + ostree commit --repo="${MONTAGEM_TEMP}/ostree/repo" --branch="${REPO_NOME}/latest" --tree=dir="${ROOTFS_TEMP}" + ostree admin deploy --sysroot="${MONTAGEM_TEMP}" --karg="root=LABEL=${LABEL_ROOT} rw ${ARG_KERNEL}" --os="${REPO_NOME}" ${OPT_NOMERGE} --retain ${REPO_NOME}/latest } -# ================================================================ -# [OSTREE]: REVERT DEPLOY -# ================================================================ -function OSTREE_REVERT_IMAGE { - ostree admin undeploy --sysroot="${OSTREE_SYS_ROOT}" 0 +# ======================================================== +# [OSTREE]: REVER COMMIT +# ======================================================== +function OSTREE_REVER { + ostree admin undeploy --sysroot="${MONTAGEM_TEMP}" 0 } -# ================================================================ -# [BOOTLOADER]: INSTALAÇÃO INICIAL -# ================================================================ -function BOOTLOADER_CREATE { - grub-install --target='x86_64-efi' --efi-directory="${OSTREE_SYS_ROOT}/boot/efi" --boot-directory="${OSTREE_SYS_ROOT}/boot/efi/EFI" --bootloader-id="${OSTREE_REP_NAME}" --removable ${OSTREE_DEV_BOOT} +# ======================================================== +# [BOOTLOADER]: CONFIGURAR GRUB EFI +# ======================================================== +function BOOTLOADER_CONFIG { + grub-install --target='x86_64-efi' --efi-directory="${MONTAGEM_TEMP}/boot/efi" --boot-directory="${MONTAGEM_TEMP}/boot/efi/EFI" --bootloader-id="${REPO_NOME}" --removable ${PARTICAO_BOOT} - local OSTREE_SYS_PATH=$(ls -d ${OSTREE_SYS_ROOT}/ostree/deploy/${OSTREE_REP_NAME}/deploy/* | head -n 1) + local CAMINHO_SYS=$(ls -d ${MONTAGEM_TEMP}/ostree/deploy/${REPO_NOME}/deploy/* | head -n 1) - rm -rfv ${OSTREE_SYS_PATH}/boot/* - mount --mkdir --rbind ${OSTREE_SYS_ROOT}/boot ${OSTREE_SYS_PATH}/boot - mount --mkdir --rbind ${OSTREE_SYS_ROOT}/ostree ${OSTREE_SYS_PATH}/sysroot/ostree + rm -rfv ${CAMINHO_SYS}/boot/* + mount --mkdir --rbind ${MONTAGEM_TEMP}/boot ${CAMINHO_SYS}/boot + mount --mkdir --rbind ${MONTAGEM_TEMP}/ostree ${CAMINHO_SYS}/sysroot/ostree - for i in /dev /proc /sys; do mount -o bind $i ${OSTREE_SYS_PATH}${i}; done - chroot ${OSTREE_SYS_PATH} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' + for i in /dev /proc /sys; do mount -o bind $i ${CAMINHO_SYS}${i}; done + chroot ${CAMINHO_SYS} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' - umount --recursive ${OSTREE_SYS_ROOT} + umount --recursive ${MONTAGEM_TEMP} } -# ================================================================ -# [CLI]: TRATAMENTO DE ARGUMENTOS -# ================================================================ -function CLI_SETUP { +# ======================================================== +# [CLI]: INTERPRETAÇÃO DE ARGUMENTOS +# ======================================================== +function CLI_EXECUTAR { CLI_ARGS=$(getopt \ --alternative \ --options='b:,c:,d:,f:,k:,t:,m::,n::,q::' \ @@ -252,92 +280,90 @@ function CLI_SETUP { CLI_VAL=${2:-} case ${CLI_ARG} in - '-b' | '--base-os') declare -g OSTREE_REP_NAME=${CLI_VAL} ;; - '-c' | '--cmdline') declare -g OSTREE_SYS_KARG=${CLI_VAL} ;; - '-d' | '--dev') declare -g OSTREE_DEV_SCSI=${CLI_VAL} ;; - '-f' | '--file') declare -g PODMAN_OPT_BUILDFILE=${CLI_VAL} ;; - '-k' | '--keymap') declare -g SYSTEM_OPT_KEYMAP=${CLI_VAL} ;; - '-t' | '--time') declare -g SYSTEM_OPT_TIMEZONE=${CLI_VAL} ;; + '-b' | '--base-os') REPO_NOME=${CLI_VAL} ;; + '-c' | '--cmdline') ARG_KERNEL=${CLI_VAL} ;; + '-d' | '--dev') DISCO_SCSI=${CLI_VAL} ;; + '-f' | '--file') ARQUIVO_CONTAINER=${CLI_VAL} ;; + '-k' | '--keymap') TECLADO=${CLI_VAL} ;; + '-t' | '--time') FUSO_HORARIO=${CLI_VAL} ;; esac [[ ${CLI_VAL@L} == 'true' ]] && CLI_VAL='1' [[ ${CLI_VAL@L} == 'false' ]] && CLI_VAL='0' - case ${CLI_ARG} in - '-m' | '--merge') declare -g OSTREE_OPT_NOMERGE=${CLI_VAL:-} ;; - '-n' | '--no-cache') declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1}; declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; - '--no-pacman-cache') declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; - '--no-podman-cache') declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} ;; - '-q' | '--quiet') declare -g CLI_QUIET=${CLI_VAL:-1} ;; + '-m' | '--merge') OPT_NOMERGE=${CLI_VAL:-} ;; + '-n' | '--no-cache') SEM_CACHE_PACMAN=${CLI_VAL:-1}; SEM_CACHE_PODMAN=${CLI_VAL:-1} ;; + '--no-pacman-cache') SEM_CACHE_PACMAN=${CLI_VAL:-1} ;; + '--no-podman-cache') SEM_CACHE_PODMAN=${CLI_VAL:-1} ;; + '-q' | '--quiet') CLI_SILENCIOSO=${CLI_VAL:-1} ;; esac if [[ ${CLI_ARG} == '--' ]]; then case ${CLI_VAL} in 'install') - ENV_CREATE_OPTS - DISK_CREATE_LAYOUT - DISK_CREATE_FORMAT - DISK_CREATE_MOUNTS - OSTREE_CREATE_REPO - OSTREE_CREATE_ROOTFS - OSTREE_CREATE_LAYOUT - OSTREE_DEPLOY_IMAGE - BOOTLOADER_CREATE + AMBIENTE_DEFINIR_OPCOES + DISCO_CRIAR_LAYOUT + DISCO_FORMATAR + DISCO_MONTAR + OSTREE_CRIA_REPO + OSTREE_CRIA_ROOTFS + OSTREE_AJUSTAR_LAYOUT + OSTREE_DEPLOY + BOOTLOADER_CONFIG ;; 'upgrade') - ENV_VERIFY_LOCAL || exit $? - ENV_CREATE_OPTS - OSTREE_CREATE_ROOTFS - OSTREE_CREATE_LAYOUT - OSTREE_DEPLOY_IMAGE + AMBIENTE_VERIFICAR || exit $? + AMBIENTE_DEFINIR_OPCOES + OSTREE_CRIA_ROOTFS + OSTREE_AJUSTAR_LAYOUT + OSTREE_DEPLOY ;; 'revert') - ENV_VERIFY_LOCAL || exit $? - ENV_CREATE_OPTS - OSTREE_REVERT_IMAGE + AMBIENTE_VERIFICAR || exit $? + AMBIENTE_DEFINIR_OPCOES + OSTREE_REVER ;; *) if [[ $(type -t ${CLI_VAL}) == 'function' ]]; then - ENV_CREATE_OPTS + AMBIENTE_DEFINIR_OPCOES ${CLI_VAL} fi ;;& * | 'help') - local USAGE=( + local AJUDA=( 'Uso:' - " ${0##*/} [opções]" + " ${0##*/} [opcoes]" 'Comandos:' - ' install : Cria deploy completo (partições, rootfs, OSTree, GRUB)' - ' upgrade : Atualiza deployment criando novo commit' - ' revert : Reverte para commit anterior' + ' install : (Criar deploy) : Particiona, formata e inicializa OSTree' + ' upgrade : (Atualizar deploy) : Cria novo commit OSTree' + ' revert : (Reverter commit) : Restaura versão 0' 'Opções:' - ' -b, --base-os string : Nome da OS base (default archlinux)' - ' -c, --cmdline string : Argumentos do kernel para boot' - ' -d, --dev string : Device SCSI para instalação' - ' -f, --file stringArray : Containerfile(s) para novo deploy' - ' -k, --keymap string : Layout do teclado TTY' - ' -t, --time string : Fuso horário' + ' -b, --base-os string : (install/upgrade) : Nome do OS base. Padrão: raglinux' + ' -c, --cmdline string : (install/upgrade) : Argumentos do kernel' + ' -d, --dev string : (install ) : ID do disco para instalação' + ' -f, --file stringArray : (install/upgrade) : Containerfile(s)' + ' -k, --keymap string : (install/upgrade) : Layout teclado' + ' -t, --time string : (install/upgrade) : Fuso horário host' 'Switches:' - ' -m, --merge : Mantém /etc existente' - ' -n, --no-cache : Ignora cache' - ' --no-pacman-cache : Ignora cache do Pacman' - ' --no-podman-cache : Ignora cache do Podman' - ' -q, --quiet : Reduz verbosidade' + ' -m, --merge : ( upgrade) : Manter /etc existente' + ' -n, --no-cache : (install/upgrade) : Ignora cache' + ' --no-pacman-cache : (install/upgrade) : Ignora cache Pacman' + ' --no-podman-cache : (install/upgrade) : Ignora cache Podman' + ' -q, --quiet : (install/upgrade) : Reduz verbosidade' ) - printf >&1 '%s\n' "${USAGE[@]}" + printf >&1 '%s\n' "${AJUDA[@]}" + if [[ ${CLI_VAL} != 'help' && -n ${CLI_VAL} ]]; then - printf >&2 '\n%s\n' "${0##*/}: comando não reconhecido '${CLI_VAL}'" + printf >&2 '\n%s\n' "${0##*/}: comando desconhecido '${CLI_VAL}'" exit 127 fi ;; esac break fi + shift 2 done } -# ================================================================ -# EXECUTA CLI -# ================================================================ -CLI_SETUP "${@}" +CLI_EXECUTAR "${@}" From 81972fe18fdccc00907e2231c6e2e243d7ead586 Mon Sep 17 00:00:00 2001 From: gabrielnasthy Date: Sun, 31 Aug 2025 15:42:44 -0400 Subject: [PATCH 03/12] minha versao --- Containerfile.base | 44 ++++ archlinux/Containerfile.base | 35 +-- post-install.sh | 14 ++ raglinux.sh | 397 +++++++++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+), 16 deletions(-) create mode 100644 Containerfile.base create mode 100755 post-install.sh create mode 100755 raglinux.sh diff --git a/Containerfile.base b/Containerfile.base new file mode 100644 index 0000000..2d4865d --- /dev/null +++ b/Containerfile.base @@ -0,0 +1,44 @@ +# | +# | ROOTFS +# | + +FROM docker.io/archlinux/archlinux:latest AS rootfs + +RUN curl https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/main/pacman.conf -o /etc/pacman.conf \ + && pacman --noconfirm --sync --needed --refresh archlinux-keyring + +# Atualiza pacman.conf com o mirror brasileiro +RUN echo "Server = https://br.mirrors.cicku.me/archlinux/\$repo/os/\$arch" > /etc/pacman.d/mirrorlist \ + && pacman -Sy --noconfirm archlinux-keyring + + +RUN pacman --noconfirm --sync --needed arch-install-scripts \ + && pacstrap -K -P /mnt \ + base base-devel linux linux-firmware ostree btrfs-progs nano git \ + plasma-desktop konsole dolphin plasma-workspace sddm \ + cockpit fwupd \ + pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber \ + bluez bluez-utils \ + gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav ffmpeg \ + podman distrobox \ + bzr buildah skopeo just \ + networkmanager fastfetch flatpak \ + && cp -av /etc/pacman.d/ /mnt/etc/ + +# | +# | BASE +# | + +FROM scratch AS base +COPY --from=rootfs /mnt / + +# Configurações do sistema RAGlinux +ARG SYSTEM_OPT_TIMEZONE="America/Cuiaba" +ARG SYSTEM_OPT_KEYMAP="br-abnt2" + +RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime \ + && echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf \ + && echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \ + && echo 'pt_BR.UTF-8 UTF-8' >> /etc/locale.gen \ + && locale-gen \ + && echo "RAGlinux" > /etc/hostname diff --git a/archlinux/Containerfile.base b/archlinux/Containerfile.base index 96dc2cf..c0be327 100644 --- a/archlinux/Containerfile.base +++ b/archlinux/Containerfile.base @@ -2,35 +2,38 @@ # | ROOTFS # | -# Build a clean system in /mnt to avoid missing files from NoExtract option in upstream FROM docker.io/archlinux/archlinux:latest AS rootfs -# Build in chroot to correctly execute hooks, this uses host's Pacman RUN curl https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/main/pacman.conf -o /etc/pacman.conf \ && pacman --noconfirm --sync --needed --refresh archlinux-keyring -# Perform a clean system installation with latest Arch Linux packages in chroot to correctly execute hooks, this uses host's Pacman RUN pacman --noconfirm --sync --needed arch-install-scripts \ - && pacstrap -K -P /mnt base \ + && pacstrap -K -P /mnt \ + base base-devel linux linux-firmware ostree btrfs-progs nano git \ + plasma-desktop konsole dolphin plasma-wayland-session sddm \ + cockpit fwupd \ + pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber \ + bluez bluez-utils \ + gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav ffmpeg \ + podman distrobox \ + bazaar buildah skopeo just \ + networkmanager fastfetch flatpak \ && cp -av /etc/pacman.d/ /mnt/etc/ # | # | BASE # | -# Reusable base template FROM scratch AS base COPY --from=rootfs /mnt / -# Clock -ARG SYSTEM_OPT_TIMEZONE -RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime +# Configurações do sistema RAGlinux +ARG SYSTEM_OPT_TIMEZONE="America/Cuiaba" +ARG SYSTEM_OPT_KEYMAP="br-abnt2" -# Keymap hook -ARG SYSTEM_OPT_KEYMAP -RUN echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf - -# Language -RUN echo 'LANG=en_US.UTF-8' > /etc/locale.conf \ - && echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \ - && locale-gen +RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime \ + && echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf \ + && echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \ + && echo 'pt_BR.UTF-8 UTF-8' >> /etc/locale.gen \ + && locale-gen \ + && echo "RAGlinux" > /etc/hostname diff --git a/post-install.sh b/post-install.sh new file mode 100755 index 0000000..c48d39f --- /dev/null +++ b/post-install.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Habilitar serviços do RAGlinux +systemctl enable sddm +systemctl enable NetworkManager +systemctl enable cockpit.socket +systemctl enable fwupd + +# Configurar usuário padrão +useradd -m -G wheel -s /bin/bash rag +echo "rag:200519" | chpasswd + +# Configurações específicas do Plasma +echo "[General]" > /etc/sddm.conf +echo "DisplayServer=wayland" >> /etc/sddm.conf diff --git a/raglinux.sh b/raglinux.sh new file mode 100755 index 0000000..93fbfa8 --- /dev/null +++ b/raglinux.sh @@ -0,0 +1,397 @@ +#!/usr/bin/env bash +set -o errexit # Exit on non-zero status +set -o nounset # Error on unset variables + +# [ENVIRONMENT]: OVERRIDE DEFAULTS +function ENV_CREATE_OPTS { + if [[ ${CLI_QUIET:-} != 1 ]]; then + set -o xtrace # Print executed commands while performing tasks + fi + + if [[ ! -d '/ostree' ]]; then + # Do not touch disks in a booted system: + declare -g OSTREE_DEV_DISK=${OSTREE_DEV_DISK:="/dev/disk/by-id/${OSTREE_DEV_SCSI}"} + declare -g OSTREE_DEV_BOOT=${OSTREE_DEV_BOOT:="${OSTREE_DEV_DISK}-part1"} + declare -g OSTREE_DEV_ROOT=${OSTREE_DEV_ROOT:="${OSTREE_DEV_DISK}-part2"} + declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/tmp/chroot'} + fi + + declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/'} + declare -g OSTREE_SYS_TREE=${OSTREE_SYS_TREE:='/tmp/rootfs'} + declare -g OSTREE_SYS_KARG=${OSTREE_SYS_KARG:='rootflags=subvol=@ rootfstype=btrfs'} + declare -g OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL:='ARCHISO_EFI'} + declare -g OSTREE_SYS_ROOT_LABEL=${OSTREE_SYS_ROOT_LABEL:='RAGLinux'} + declare -g OSTREE_OPT_NOMERGE=${OSTREE_OPT_NOMERGE='--no-merge'} + declare -g OSTREE_REP_NAME=${OSTREE_REP_NAME:='raglinux'} + + if [[ -n ${SYSTEM_OPT_TIMEZONE:-} ]]; then + # Do not modify host's time unless explicitly specified + timedatectl set-timezone ${SYSTEM_OPT_TIMEZONE} + timedatectl set-ntp 1 + fi + declare -g SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE:='America/Cuiaba'} + declare -g SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP:='br-abnt2'} + + declare -g PODMAN_OPT_BUILDFILE=${PODMAN_OPT_BUILDFILE:="${0%/*}/Containerfile.base:ostree/base"} + declare -g PODMAN_OPT_NOCACHE=${PODMAN_OPT_NOCACHE:='0'} + declare -g PACMAN_OPT_NOCACHE=${PACMAN_OPT_NOCACHE:='0'} +} + +# [ENVIRONMENT]: OSTREE CHECK +function ENV_VERIFY_LOCAL { + if [[ ! -d '/ostree' ]]; then + printf >&2 '\e[31m%s\e[0m\n' 'OSTree could not be found in: /ostree' + return 1 + fi +} + +# [ENVIRONMENT]: BUILD DEPENDENCIES +function ENV_CREATE_DEPS { + # Skip in OSTree as filesystem is read-only + if ! ENV_VERIFY_LOCAL 2>/dev/null; then + pacman --noconfirm --sync --needed $@ + fi +} + +# [DISK]: PARTITIONING (GPT+UEFI) - SKIP AS PARTITIONS ALREADY EXIST +function DISK_CREATE_LAYOUT { + echo "Partições já existem, pulando criação..." + return 0 +} + +# [DISK]: FILESYSTEM (ESP+BTRFS) - SKIP AS FILESYSTEMS ALREADY EXIST +function DISK_CREATE_FORMAT { + echo "Sistemas de arquivo já existem, pulando formatação..." + return 0 +} + +# [DISK]: BUILD DIRECTORY +function DISK_CREATE_MOUNTS { + # Criar diretório de montagem se não existir + mkdir -p ${OSTREE_SYS_ROOT} + + # Montar partição root temporariamente para criar subvolumes + mount ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} + + # Criar subvolumes BTRFS + btrfs subvolume create ${OSTREE_SYS_ROOT}/@ || true + btrfs subvolume create ${OSTREE_SYS_ROOT}/@home || true + btrfs subvolume create ${OSTREE_SYS_ROOT}/@var || true + btrfs subvolume create ${OSTREE_SYS_ROOT}/@ostree || true + + # Desmontar e remontar com subvolumes + umount ${OSTREE_SYS_ROOT} + mount -o subvol=@ ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} + + # Criar diretórios e montar subvolumes + mkdir -p ${OSTREE_SYS_ROOT}/{home,var,ostree} + mount -o subvol=@home ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/home + mount -o subvol=@var ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/var + mount -o subvol=@ostree ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/ostree + + # Montar partição EFI + mkdir -p ${OSTREE_SYS_ROOT}/boot/efi + mount ${OSTREE_DEV_BOOT} ${OSTREE_SYS_ROOT}/boot/efi +} + +# [OSTREE]: FIRST INITIALIZATION +function OSTREE_CREATE_REPO { + ENV_CREATE_DEPS ostree which + ostree admin init-fs --sysroot="${OSTREE_SYS_ROOT}" --modern ${OSTREE_SYS_ROOT} + ostree admin stateroot-init --sysroot="${OSTREE_SYS_ROOT}" ${OSTREE_REP_NAME} + ostree init --repo="${OSTREE_SYS_ROOT}/ostree/repo" --mode='bare' + ostree config --repo="${OSTREE_SYS_ROOT}/ostree/repo" set sysroot.bootprefix 1 +} + +# [OSTREE]: BUILD ROOTFS +function OSTREE_CREATE_ROOTFS { + # Add support for overlay storage driver in LiveCD + if [[ $(df --output=fstype / | tail --lines 1) = 'overlay' ]]; then + ENV_CREATE_DEPS fuse-overlayfs + declare -x TMPDIR='/mnt/podman' + local PODMAN_OPT_GLOBAL=( + --root="${TMPDIR}/storage" + --tmpdir="${TMPDIR}/tmp" + ) + fi + + # Install Podman + ENV_CREATE_DEPS podman + + # Copy Pacman package cache into /var by default (to avoid duplication) + if [[ ${PACMAN_OPT_NOCACHE} == 0 ]]; then + mkdir -p "${TMPDIR:-}/var/cache/pacman" + local PODMAN_OPT_BUILD=( + --volume="${TMPDIR:-}/var/cache/pacman:${TMPDIR:-}/var/cache/pacman" + ) + fi + + # Skip Podman layer cache if requested + if [[ ${PODMAN_OPT_NOCACHE} == 1 ]]; then + local PODMAN_OPT_BUILD=( + ${PODMAN_OPT_BUILD[@]} + --no-cache='1' + ) + fi + + # Podman: create rootfs from multiple Containerfiles + for TARGET in ${PODMAN_OPT_BUILDFILE//,/ }; do + local PODMAN_OPT_IMG=(${TARGET%:*}) + local PODMAN_OPT_TAG=(${TARGET#*:}) + podman ${PODMAN_OPT_GLOBAL[@]} build \ + ${PODMAN_OPT_BUILD[@]} \ + --file="${PODMAN_OPT_IMG}" \ + --tag="${PODMAN_OPT_TAG}" \ + --cap-add='SYS_ADMIN' \ + --build-arg="OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL}" \ + --build-arg="OSTREE_SYS_ROOT_LabEL=${OSTREE_SYS_ROOT_LABEL}" \ + --build-arg="SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE}" \ + --build-arg="SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP}" \ + --pull='newer' + done + + # Ostreeify: retrieve rootfs (workaround: `podman build --output local` doesn't preserve ownership) + rm -rf ${OSTREE_SYS_TREE} + mkdir -p ${OSTREE_SYS_TREE} + podman ${PODMAN_OPT_GLOBAL[@]} export $(podman ${PODMAN_OPT_GLOBAL[@]} create ${PODMAN_OPT_TAG} bash) | tar -xC ${OSTREE_SYS_TREE} +} + +# [OSTREE]: DIRECTORY STRUCTURE +function OSTREE_CREATE_LAYOUT { + # Doing it here allows the container to be runnable/debuggable and Containerfile reusable + mv ${OSTREE_SYS_TREE}/etc ${OSTREE_SYS_TREE}/usr/ + + rm -r ${OSTREE_SYS_TREE}/home + ln -s var/home ${OSTREE_SYS_TREE}/home + + rm -r ${OSTREE_SYS_TREE}/mnt + ln -s var/mnt ${OSTREE_SYS_TREE}/mnt + + rm -r ${OSTREE_SYS_TREE}/opt + ln -s var/opt ${OSTREE_SYS_TREE}/opt + + rm -r ${OSTREE_SYS_TREE}/root + ln -s var/roothome ${OSTREE_SYS_TREE}/root + + rm -r ${OSTREE_SYS_TREE}/srv + ln -s var/srv ${OSTREE_SYS_TREE}/srv + + mkdir ${OSTREE_SYS_TREE}/sysroot + ln -s sysroot/ostree ${OSTREE_SYS_TREE}/ostree + + rm -r ${OSTREE_SYS_TREE}/usr/local + ln -s ../var/usrlocal ${OSTREE_SYS_TREE}/usr/local + + printf >&1 '%s\n' 'Creating tmpfiles' + echo 'd /var/home 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/log/journal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/mnt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/opt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/roothome 0700 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/srv 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/bin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/etc 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/games 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/include 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/man 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/sbin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/share 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /var/usrlocal/src 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + echo 'd /run/media 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf + + # Only retain information about Pacman packages in new rootfs + mv ${OSTREE_SYS_TREE}/var/lib/pacman ${OSTREE_SYS_TREE}/usr/lib/ + sed -i \ + -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ + -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ + ${OSTREE_SYS_TREE}/usr/etc/pacman.conf + + # Allow Pacman to store update notice id during unlock mode + mkdir ${OSTREE_SYS_TREE}/usr/lib/pacmanlocal + + # OSTree mounts /ostree/deploy/${OSTREE_REP_NAME}/var to /var + rm -r ${OSTREE_SYS_TREE}/var/* +} + +# [OSTREE]: CREATE COMMIT +function OSTREE_DEPLOY_IMAGE { + # Update repository and boot entries in GRUB2 + ostree commit --repo="${OSTREE_SYS_ROOT}/ostree/repo" --branch="${OSTREE_REP_NAME}/latest" --tree=dir="${OSTREE_SYS_TREE}" + ostree admin deploy --sysroot="${OSTREE_SYS_ROOT}" --karg="root=LABEL=${OSTREE_SYS_ROOT_LABEL} rw ${OSTREE_SYS_KARG}" --os="${OSTREE_REP_NAME}" ${OSTREE_OPT_NOMERGE} --retain ${OSTREE_REP_NAME}/latest +} + +# [OSTREE]: UNDO COMMIT +function OSTREE_REVERT_IMAGE { + ostree admin undeploy --sysroot="${OSTREE_SYS_ROOT}" 0 +} + +# [BOOTLOADER]: FIRST BOOT +function BOOTLOADER_CREATE { + grub-install --target='x86_64-efi' --efi-directory="${OSTREE_SYS_ROOT}/boot/efi" --boot-directory="${OSTREE_SYS_ROOT}/boot/efi/EFI" --bootloader-id="${OSTREE_REP_NAME}" --removable ${OSTREE_DEV_BOOT} + + local OSTREE_SYS_PATH=$(ls -d ${OSTREE_SYS_ROOT}/ostree/deploy/${OSTREE_REP_NAME}/deploy/* | head -n 1) + + rm -rfv ${OSTREE_SYS_PATH}/boot/* + mount --mkdir --rbind ${OSTREE_SYS_ROOT}/boot ${OSTREE_SYS_PATH}/boot + mount --mkdir --rbind ${OSTREE_SYS_ROOT}/ostree ${OSTREE_SYS_PATH}/sysroot/ostree + + for i in /dev /proc /sys; do mount -o bind $i ${OSTREE_SYS_PATH}${i}; done + chroot ${OSTREE_SYS_PATH} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' + + umount --recursive ${OSTREE_SYS_ROOT} +} + +# [CLI]: TASK FINECONTROL +function CLI_SETUP { + CLI_ARGS=$(getopt \ + --alternative \ + --options='b:,c:,d:,f:,k:,t:,m::,n::,q::' \ + --longoptions='base-os:,cmdline:,dev:,file:,keymap:,time:,merge::,no-cache::,no-pacman-cache::,no-podman-cache::,quiet::' \ + --name="${0##*/}" \ + -- "${@}" + ) + + # Rewrite "${@}" + eval set -- "${CLI_ARGS}" + + # Arguments + while [[ ${#} > 0 ]]; do + CLI_ARG=${1:-} + CLI_VAL=${2:-} + + # Options + case ${CLI_ARG} in + '-b' | '--base-os') + declare -g OSTREE_REP_NAME=${CLI_VAL} + ;; + + '-c' | '--cmdline') + declare -g OSTREE_SYS_KARG=${CLI_VAL} + ;; + + '-d' | '--dev') + declare -g OSTREE_DEV_SCSI=${CLI_VAL} + ;; + + '-f' | '--file') + declare -g PODMAN_OPT_BUILDFILE=${CLI_VAL} + ;; + + '-k' | '--keymap') + declare -g SYSTEM_OPT_KEYMAP=${CLI_VAL} + ;; + + '-t' | '--time') + declare -g SYSTEM_OPT_TIMEZONE=${CLI_VAL} + ;; + esac + + # Switches + [[ ${CLI_VAL@L} == 'true' ]] && CLI_VAL='1' + [[ ${CLI_VAL@L} == 'false' ]] && CLI_VAL='0' + case ${CLI_ARG} in + '-m' | '--merge') + declare -g OSTREE_OPT_NOMERGE=${CLI_VAL:-} + ;; + + '-n' | '--no-cache') + declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} + declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} + ;; + + '--no-pacman-cache') + declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} + ;; + + '--no-podman-cache') + declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} + ;; + + '-q' | '--quiet') + declare -g CLI_QUIET=${CLI_VAL:-1} + ;; + esac + + # Commands + if [[ ${CLI_ARG} == '--' ]]; then + case ${CLI_VAL} in + 'install') + ENV_CREATE_OPTS + + DISK_CREATE_LAYOUT + DISK_CREATE_FORMAT + DISK_CREATE_MOUNTS + + OSTREE_CREATE_REPO + OSTREE_CREATE_ROOTFS + OSTREE_CREATE_LAYOUT + OSTREE_DEPLOY_IMAGE + + BOOTLOADER_CREATE + ;; + + 'upgrade') + ENV_VERIFY_LOCAL || exit $? + ENV_CREATE_OPTS + + OSTREE_CREATE_ROOTFS + OSTREE_CREATE_LAYOUT + OSTREE_DEPLOY_IMAGE + ;; + + 'revert') + ENV_VERIFY_LOCAL || exit $? + ENV_CREATE_OPTS + + OSTREE_REVERT_IMAGE + ;; + + *) + if [[ $(type -t ${CLI_VAL}) == 'function' ]]; then + ENV_CREATE_OPTS + ${CLI_VAL} + fi + ;;& + + * | 'help') + local USAGE=( + 'Usage:' + " ${0##*/} [options]" + 'Commands:' + ' install : (Create deployment) : Partitions, formats and initializes a new OSTree repository' + ' upgrade : (Update deployment) : Creates a new OSTree commit' + ' revert : (Update deployment) : Rolls back version 0' + 'Options:' + ' -b, --base-os string : (install/upgrade) : Name of OS to use as a base. Defaults to raglinux' + ' -c, --cmdline string : (install/upgrade) : List of kernel arguments for boot' + ' -d, --dev string : (install ) : Device SCSI (ID-LINK) for new installation' + ' -f, --file stringArray : (install/upgrade) : Containerfile(s) for new deployment' + ' -k, --keymap string : (install/upgrade) : TTY keyboard layout for new deployment' + ' -t, --time string : (install/upgrade) : Update host timezone for new deployment' + 'Switches:' + ' -m, --merge : ( upgrade) : Retain contents of /etc for existing deployment' + ' -n, --no-cache : (install/upgrade) : Skip any cached data (note: implied for first deployment)' + ' --no-pacman-cache : (install/upgrade) : Skip Pacman package cache' + ' --no-podman-cache : (install/upgrade) : Skip Podman layer cache' + ' -q, --quiet : (install/upgrade) : Reduce verbosity' + ) + printf >&1 '%s\n' "${USAGE[@]}" + + if [[ ${CLI_VAL} != 'help' && -n ${CLI_VAL} ]]; then + printf >&2 '\n%s\n' "${0##*/}: unrecognized command '${CLI_VAL}'" + exit 127 + fi + ;; + esac + break + fi + + # Continue to the next argument + shift 2 + done +} + +CLI_SETUP "${@}" From 3bc6b2d12420bb801968da266e522be0326a7dba Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:08:01 -0400 Subject: [PATCH 04/12] Update README.md --- README.md | 258 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 144 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index a39ab15..39755e9 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,190 @@ -## OSTree in Arch Linux using Podman - -Massive shout-out to [M1cha](https://github.com/M1cha/) for making this possible ([M1cha/archlinux-ostree](https://github.com/M1cha/archlinux-ostree)). - -### Overview - -This is a helper script which aids in curating your own setup by demonstrating how to: -1. Build an immutable OSTree image by using rootfs from a Podman Containerfile. -2. Partition and prepare UEFI/GPT disks for a minimal OSTree host system. -3. Generate OSTree repository in a empty filesystem. -4. Integrate OSTree with GRUB2 bootloader. -5. Upgrade an existing OSTree repository with a new rootfs image. - -### Disk structure - -```console -/ -├── boot -│   └── efi -└── ostree - ├── deploy - │   └── archlinux - └── repo - ├── config - ├── extensions - ├── objects - ├── refs - ├── state - └── tmp +Perfeito, Gabriel! Vou criar um **README.md completo** para o seu projeto **RAGLinux**, documentando todo o processo, os scripts que você tem, os problemas enfrentados e como gerenciar o sistema após a instalação. Você poderá colocar diretamente no GitHub. + +--- + +```markdown +# RAGLinux + +RAGLinux é um sistema baseado em **Arch Linux** imutável, gerenciado com **OSTree** e construído via **Podman**. Este projeto automatiza a criação de rootfs, subvolumes Btrfs, deploy OSTree, configuração de bootloader e integração de pacotes via container. + +--- + +## 🚀 Estrutura do projeto + ``` -### Persistence +raglinux/ +├── raglinux.sh # Script principal de instalação e gerenciamento +├── Containerfile.base # Containerfile para criar rootfs +├── README.md # Documentação do projeto +├── post-install.sh # (Opcional) script pós-instalação +├── archlinux/ # Configurações específicas do Arch +├── cachyos/ # Configurações de build adicionais +└── Containerfile.host.example -Everything is deleted between deployments **except** for: -- `/dev` partitions which OSTree does not reside on are untouched. -- `/etc` only if `--merge` option is specified. -- `/home` is symlinked to `/var/home` (see below). -- `/var` data here is mounted from `/ostree/deploy/archlinux/var` to avoid duplication. +```` -Notes: -- `/var/cache/podman` is populated _only_ after the first deployment (to avoid including old data from the build machine), this speeds up consecutive builds. -- `/var/lib/containers` same as above but for Podman layers and images. Base images are updated automatically during `upgrade` command. +--- -### Technology stack +## 🛠 Scripts principais -- OSTree -- Podman with CRUN and Native-Overlayfs -- GRUB2 -- XFS _(not required)_ +### `raglinux.sh` -### Motivation +- Responsável por: + - Preparar ambiente + - Montar partições e subvolumes Btrfs + - Inicializar repositório OSTree + - Criar rootfs via Podman + - Configurar links simbólicos e tmpfiles + - Criar commit OSTree e deploy + - Instalar GRUB EFI e gerar `grub.cfg` -My vision is to build a secure and minimal base system which is resilient against breakage and provides setup automation to reduce the burden of doing manual tasks. This can be achieved by: +- Comandos disponíveis: + ```bash + ./raglinux.sh install # Cria deployment inicial + ./raglinux.sh upgrade # Cria novo commit OSTree + ./raglinux.sh revert # Reverte para deployment 0 + ./raglinux.sh help # Exibe documentação do CLI +```` -- Git. -- Read-only system files. -- Restore points. -- Automatic deployment, installation & configuration. -- Using only required components like kernel/firmware/driver, microcode and GGC in the base. -- Doing the rest in temporary namespaces such as Podman. +* Opções importantes: -### Goal + ```text + -b, --base-os : Nome do OS (default raglinux) + -c, --cmdline : Kernel args + -d, --dev : Device SCSI para instalação + -f, --file : Containerfile(s) para build + -k, --keymap : Layout TTY + -t, --time : Timezone + -m, --merge : Retém /etc em upgrade + -n, --no-cache : Ignora cache (Pacman + Podman) + -q, --quiet : Reduz saída + ``` -- Reproducible deployments. -- Versioned rollbacks. -- Immutable filesystem. -- Distribution agnostic toolset. -- Configuration management. -- Rootfs creation via containers. -- Each deployment does a factory reset of system's configuration _(unless overridden)_. +--- -### Similar projects +### `Containerfile.base` -- **[Elemental Toolkit](https://github.com/rancher/elemental-toolkit)** -- **[KairOS](https://github.com/kairos-io/kairos)** -- **[BootC](https://github.com/containers/bootc)** -- [NixOS](https://nixos.org) -- [ABRoot](https://github.com/Vanilla-OS/ABRoot) -- [Transactional Update + BTRFS snapshots](https://microos.opensuse.org) -- [AshOS](https://github.com/ashos/ashos) -- [LinuxKit](https://github.com/linuxkit/linuxkit) +* Base para construção do rootfs +* Instala pacotes essenciais via `pacstrap`: -## Usage + * `base`, `base-devel`, `linux`, `linux-firmware`, `ostree`, `btrfs-progs`, `nano`, `git` + * `plasma-desktop`, `konsole`, `dolphin`, `plasma-workspace`, `sddm` + * `cockpit`, `fwupd`, `pipewire`, `wireplumber`, `bluez`, `gst-plugins-*`, `ffmpeg` + * `podman`, `distrobox`, `bzr`, `buildah`, `skopeo`, `just`, `networkmanager`, `fastfetch`, `flatpak` +* Configura timezone e keymap +* Configura `locale` e hostname -1. **Boot into any Arch Linux system:** +--- - For instance, using a live CD/USB ISO image from: [Arch Linux Downloads](https://archlinux.org/download). +## ⚠️ Problemas resolvidos durante a instalação -2. **Clone this repository:** +1. **Espaço insuficiente no LiveCD (`airootfs`)** - ```console - $ sudo pacman -Sy git - $ git clone https://github.com/GrabbenD/ostree-utility.git && cd ostree-utility + * Solução: Usei `/mnt/podman` para TMPDIR e root do Podman. + + ```bash + export TMPDIR=/mnt/podman/tmp ``` -3. **Find `ID-LINK` for installation device where OSTree image will be deployed:** +2. **Erro de volume Podman não encontrado** - ```console - $ lsblk -o NAME,TYPE,FSTYPE,MODEL,ID-LINK,SIZE,MOUNTPOINTS,LABEL - NAME TYPE FSTYPE MODEL ID-LINK SIZE MOUNTPOINTS LABEL - sdb disk Virtual Disk scsi-360022480c22be84f8a61b39bbaed612f 300G - ├─sdb1 part vfat scsi-360022480c22be84f8a61b39bbaed612f-part1 256M SYS_BOOT - ├─sdb2 part xfs scsi-360022480c22be84f8a61b39bbaed612f-part2 24.7G SYS_ROOT - └─sdb3 part xfs scsi-360022480c22be84f8a61b39bbaed612f-part3 275G SYS_HOME - ``` + * Solução: Criei diretórios para cache do pacman antes do build: -4. **Perform a takeover installation:** + ```bash + mkdir -p /mnt/podman/var/cache/pacman + ``` - **⚠️ WARNING ⚠️** +3. **GRUB não instalado no chroot** - `ostree.sh` is destructive and has no prompts while partitioning the specified disk, **proceed with caution**: + * Solução: Montar `/boot` e `/ostree` dentro do deployment e usar `chroot`: - ```console - $ chmod +x ostree.sh - $ sudo ./ostree.sh install --dev scsi-360022480c22be84f8a61b39bbaed612f + ```bash + for i in /dev /proc /sys; do mount -o bind $i ${DEPLOY_PATH}${i}; done + chroot ${DEPLOY_PATH} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' ``` - ⚙️ Update your BIOS boot order to access the installation. +4. **Pacman inacessível no root OSTree** - 💡 Default login is: `root` / `ostree` + * Solução: Mantive cache e DB em `/usr/lib/pacman` e usei Podman ou Flatpak para instalar apps. - 💡 Use different Containerfile(s) with `--file FILE1:TAG1,FILE2:TAG2` option +--- -5. **Upgrade an existing installation:** +## 🗂 Estrutura de rootfs OSTree - While booted into a OSTree system, use: +``` +/ # Root imutável +/home # Subvolume @home +/var # Subvolume @var +/ostree # Subvolume @ostree (deployments) +/boot/efi # EFI boot +/usr/lib/pacman # Pacman DB e cache +/usr/lib/tmpfiles.d # Configuração tmpfiles +``` - ```console - $ sudo ./ostree.sh upgrade - ``` +* Root é **imutável** +* Atualizações são via **OSTree commits** +* Rollback possível se algo der errado - 💡 Use `--merge` option to preserve contents of `/etc` +--- -6. **Revert to previous commit:** +## 🖥 Gerenciamento do sistema - To undo the latest deployment _(0)_; boot into the previous configuration _(1)_ and execute: +* Ver deploys: - ```console - $ sudo ./ostree.sh revert - ``` +```bash +ostree admin status +``` -## Tips +* Deploy novo commit: -### Read-only +```bash +sudo ostree admin deploy raglinux/latest +``` -This attribute can be temporarily removed with Overlay filesystem which allows you to modify read-only paths without persisting the changes: +* Reverter: -```console -$ ostree admin unlock +```bash +sudo ostree admin undeploy --rollback ``` -### Outdated repository cache +* Instalar apps sem tocar root: + + * Flatpak + * Podman / Distrobox (containers) + * Diretórios em `/home/` + +--- + +## 🌐 Mirror brasileiro + +* Pacman configurado para: + +``` +Server = https://br.mirrors.cicku.me/archlinux/$repo/os/$arch +``` + +--- + +## 💡 Dicas finais + +* Sempre use `raglinux.sh` para instalação e upgrades. +* Para instalar apps de forma segura, utilize **containers ou flatpak**. +* Lembre-se que `/` é imutável; alterações diretas fora do OSTree não persistem. + +--- + +### Autor + +Gabriel Aguiar Rocha – [GitHub](https://github.com/gabrielrocha) + +--- + +``` -> `error: failed retrieving file '{name}.pkg.tar.zst' from {source} : The requested URL returned error: 404` +--- -Your persistent cache is out of sync with upstream, this can be resolved with: +Se você quiser, posso criar uma **versão ainda mais detalhada**, incluindo **passo-a-passo de todo o build**, **comandos do Podman e OSTree**, e **prints de erros comuns e suas soluções**, para servir como documentação completa para qualquer usuário do RAGLinux. -```console -$ ./ostree.sh upgrade --no-podman-cache +Quer que eu faça essa versão expandida? ``` From 054a8f54c429b49e8637c1396bb9323f123be793 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:08:10 -0400 Subject: [PATCH 05/12] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 39755e9..60cb068 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -Perfeito, Gabriel! Vou criar um **README.md completo** para o seu projeto **RAGLinux**, documentando todo o processo, os scripts que você tem, os problemas enfrentados e como gerenciar o sistema após a instalação. Você poderá colocar diretamente no GitHub. --- From dc5f55286d554969df30a6327ba39a8844275c05 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:10:08 -0400 Subject: [PATCH 06/12] Update README.md --- README.md | 240 +++++++++++++++++++++++------------------------------- 1 file changed, 103 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 60cb068..801cd76 100644 --- a/README.md +++ b/README.md @@ -1,189 +1,155 @@ +----- ---- - -```markdown # RAGLinux -RAGLinux é um sistema baseado em **Arch Linux** imutável, gerenciado com **OSTree** e construído via **Podman**. Este projeto automatiza a criação de rootfs, subvolumes Btrfs, deploy OSTree, configuração de bootloader e integração de pacotes via container. +**RAGLinux** é um sistema operacional baseado em **Arch Linux** com uma abordagem moderna e robusta: um sistema de arquivos raiz **imutável**, gerenciado de forma atômica pelo **OSTree** e construído com a flexibilidade do **Podman**. ---- +O objetivo deste projeto é fornecer a estabilidade de um sistema imutável, onde as atualizações são seguras e reversíveis, combinada com a vasta gama de pacotes e a filosofia "faça você mesmo" do Arch Linux. -## 🚀 Estrutura do projeto +----- -``` +## 🌟 Principais Características -raglinux/ -├── raglinux.sh # Script principal de instalação e gerenciamento -├── Containerfile.base # Containerfile para criar rootfs -├── README.md # Documentação do projeto -├── post-install.sh # (Opcional) script pós-instalação -├── archlinux/ # Configurações específicas do Arch -├── cachyos/ # Configurações de build adicionais -└── Containerfile.host.example + * **Sistema Imutável**: O diretório raiz (`/`) é montado como somente leitura, prevenindo modificações acidentais e garantindo que cada "versão" do sistema seja consistente e testada. + * **Atualizações Atômicas**: As atualizações são aplicadas em uma nova "árvore" do sistema. A mudança para a nova versão ocorre em uma única operação (geralmente na reinicialização), eliminando o risco de um sistema quebrar no meio de uma atualização. + * **Rollbacks Simples**: Se uma atualização causar problemas, reverter para a versão anterior funcional é um comando simples e instantâneo. + * **Construção via Containers**: A imagem base do sistema é construída dentro de um container Podman, garantindo um ambiente de build limpo, reprodutível e isolado. + * **Separação Clara**: O sistema operacional é estritamente separado dos dados e configurações do usuário, que residem em subvolumes Btrfs separados (`/home`, `/var`). -```` +----- ---- +## 🛠️ Tecnologias Utilizadas -## 🛠 Scripts principais + * **Base System**: [Arch Linux](https://archlinux.org/) + * **Gerenciamento Atômico**: [OSTree](https://ostreedev.github.io/ostree/) + * **Sistema de Arquivos**: [Btrfs](https://btrfs.wiki.kernel.org/) + * **Construção (Build)**: [Podman](https://podman.io/) + * **Bootloader**: [GRUB](https://www.gnu.org/software/grub/) -### `raglinux.sh` +----- -- Responsável por: - - Preparar ambiente - - Montar partições e subvolumes Btrfs - - Inicializar repositório OSTree - - Criar rootfs via Podman - - Configurar links simbólicos e tmpfiles - - Criar commit OSTree e deploy - - Instalar GRUB EFI e gerar `grub.cfg` +## 🚀 Estrutura do Projeto -- Comandos disponíveis: - ```bash - ./raglinux.sh install # Cria deployment inicial - ./raglinux.sh upgrade # Cria novo commit OSTree - ./raglinux.sh revert # Reverte para deployment 0 - ./raglinux.sh help # Exibe documentação do CLI -```` +``` +raglinux/ +├── raglinux.sh # Script principal de instalação e gerenciamento +├── Containerfile.base # Define a imagem base do sistema (pacotes e configs) +├── post-install.sh # (Opcional) Script para configurações pós-instalação +├── archlinux/ # Configurações específicas do Arch +├── cachyos/ # (Opcional) Configurações para builds alternativas +└── Containerfile.host.example # Exemplo para customizações do host +``` -* Opções importantes: +----- - ```text - -b, --base-os : Nome do OS (default raglinux) - -c, --cmdline : Kernel args - -d, --dev : Device SCSI para instalação - -f, --file : Containerfile(s) para build - -k, --keymap : Layout TTY - -t, --time : Timezone - -m, --merge : Retém /etc em upgrade - -n, --no-cache : Ignora cache (Pacman + Podman) - -q, --quiet : Reduz saída - ``` +## ⚙️ Uso e Gerenciamento ---- +O script `raglinux.sh` é a principal ferramenta para interagir com o sistema em nível de build e deploy. -### `Containerfile.base` +### Instalação Inicial -* Base para construção do rootfs -* Instala pacotes essenciais via `pacstrap`: +Para criar o primeiro deployment do sistema em um dispositivo de bloco (ex: `/dev/sda`). - * `base`, `base-devel`, `linux`, `linux-firmware`, `ostree`, `btrfs-progs`, `nano`, `git` - * `plasma-desktop`, `konsole`, `dolphin`, `plasma-workspace`, `sddm` - * `cockpit`, `fwupd`, `pipewire`, `wireplumber`, `bluez`, `gst-plugins-*`, `ffmpeg` - * `podman`, `distrobox`, `bzr`, `buildah`, `skopeo`, `just`, `networkmanager`, `fastfetch`, `flatpak` -* Configura timezone e keymap -* Configura `locale` e hostname +```bash +# Exemplo de uso +./raglinux.sh install --dev /dev/sda --keymap br-abnt2 --time America/Sao_Paulo +``` ---- +### Atualizando o Sistema (Upgrade) -## ⚠️ Problemas resolvidos durante a instalação +Isso irá construir uma nova imagem, criar um novo commit no OSTree e prepará-lo para ser o próximo boot. -1. **Espaço insuficiente no LiveCD (`airootfs`)** +```bash +# Cria um novo commit OSTree com as últimas atualizações +./raglinux.sh upgrade +``` - * Solução: Usei `/mnt/podman` para TMPDIR e root do Podman. +Após o upgrade, reinicie o sistema para aplicar a nova versão. - ```bash - export TMPDIR=/mnt/podman/tmp - ``` +### Revertendo uma Atualização (Rollback) -2. **Erro de volume Podman não encontrado** +Caso a última atualização apresente algum problema, você pode facilmente reverter. - * Solução: Criei diretórios para cache do pacman antes do build: +```bash +# Reverte para o deployment anterior (marcado como 0) +./raglinux.sh revert +``` - ```bash - mkdir -p /mnt/podman/var/cache/pacman - ``` +### Opções do Script `raglinux.sh` -3. **GRUB não instalado no chroot** +| Opção | Argumento Longo | Descrição | Padrão | +| :--- | :--- | :--- |:--- | +| `-b` | `--base-os` | Nome do sistema operacional para o repositório OSTree. | `raglinux` | +| `-c` | `--cmdline` | Argumentos extras para a linha de comando do Kernel. | | +| `-d` | `--dev` | Dispositivo de bloco (SCSI/NVMe) para a instalação. | | +| `-f` | `--file` | Caminho para o(s) `Containerfile`(s) a serem usados no build. | | +| `-k` | `--keymap` | Layout de teclado para o console (TTY). | | +| `-t` | `--time` | Fuso horário (Timezone) no formato `Região/Cidade`. | | +| `-m` | `--merge` | Mantém o diretório `/etc` durante um upgrade. | | +| `-n` | `--no-cache` | Ignora o cache do Pacman e do Podman durante o build. | | +| `-q` | `--quiet` | Reduz a quantidade de logs exibidos na saída. | | - * Solução: Montar `/boot` e `/ostree` dentro do deployment e usar `chroot`: +----- - ```bash - for i in /dev /proc /sys; do mount -o bind $i ${DEPLOY_PATH}${i}; done - chroot ${DEPLOY_PATH} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' - ``` +## 📦 Gerenciamento de Aplicações -4. **Pacman inacessível no root OSTree** +Em um sistema imutável, o gerenciamento de pacotes tradicional (`pacman -S ...`) não é usado diretamente no sistema host. Em vez disso, a instalação de aplicações de usuário é feita de forma isolada: - * Solução: Mantive cache e DB em `/usr/lib/pacman` e usei Podman ou Flatpak para instalar apps. + * **Flatpak**: O método recomendado para aplicações gráficas. Elas rodam em seu próprio sandbox e não alteram o sistema base. + * **Podman / Distrobox**: Ideal para ferramentas de linha de comando e ambientes de desenvolvimento. Crie containers com as distribuições e pacotes que precisar, sem "sujar" o sistema host. + * **Binários em `/home`**: Para aplicações simples que não requerem dependências complexas, você pode executá-las a partir do seu diretório pessoal. ---- +----- -## 🗂 Estrutura de rootfs OSTree +## 🗂️ Estrutura do Sistema de Arquivos (Pós-instalação) -``` -/ # Root imutável -/home # Subvolume @home -/var # Subvolume @var -/ostree # Subvolume @ostree (deployments) -/boot/efi # EFI boot -/usr/lib/pacman # Pacman DB e cache -/usr/lib/tmpfiles.d # Configuração tmpfiles -``` +O RAGLinux utiliza subvolumes Btrfs para separar os dados do sistema. -* Root é **imutável** -* Atualizações são via **OSTree commits** -* Rollback possível se algo der errado + * `/` (raiz): **Imutável**. Gerenciado pelo OSTree. + * `/home`: Subvolume `@home`. **Mutável**. Armazena os arquivos e configurações dos usuários. + * `/var`: Subvolume `@var`. **Mutável**. Contém dados variáveis como logs, caches de aplicações, etc. + * `/ostree`: Subvolume `@ostree`. Contém os deployments (versões) do sistema operacional. + * `/boot/efi`: Partição EFI para o bootloader. ---- +----- -## 🖥 Gerenciamento do sistema +## 🧠 Desafios Resolvidos Durante o Desenvolvimento -* Ver deploys: +1. **Espaço Insuficiente no LiveCD (`airootfs`)** -```bash -ostree admin status -``` + * **Problema**: O ambiente de instalação do Arch tem um `tmpfs` limitado, que estourava durante o build do container. + * **Solução**: Direcionar o diretório temporário e a raiz do Podman para o disco de destino (`/mnt`), que possui espaço de sobra. + ```bash + export TMPDIR=/mnt/podman/tmp + # Configurar /mnt/podman como storage root do Podman + ``` -* Deploy novo commit: +2. **Volume do Podman Não Encontrado** -```bash -sudo ostree admin deploy raglinux/latest -``` + * **Problema**: O Podman não conseguia montar o cache do Pacman pois o diretório de destino não existia no host antes do build. + * **Solução**: Criar manualmente a estrutura de diretórios do cache antes de invocar o comando `podman build`. + ```bash + mkdir -p /mnt/podman/var/cache/pacman + ``` -* Reverter: +3. **GRUB Não se Instalava Corretamente no Chroot** -```bash -sudo ostree admin undeploy --rollback -``` - -* Instalar apps sem tocar root: - - * Flatpak - * Podman / Distrobox (containers) - * Diretórios em `/home/` - ---- + * **Problema**: O comando `grub-mkconfig` falhava por não encontrar os dispositivos e informações do sistema quando executado de um chroot simples. + * **Solução**: Fazer o bind mount dos pseudo-sistemas de arquivos (`/dev`, `/proc`, `/sys`) do host para dentro do ambiente chroot antes de executar o comando. + ```bash + for i in /dev /proc /sys; do mount -o bind $i ${DEPLOY_PATH}${i}; done + chroot ${DEPLOY_PATH} grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg + ``` -## 🌐 Mirror brasileiro - -* Pacman configurado para: - -``` -Server = https://br.mirrors.cicku.me/archlinux/$repo/os/$arch -``` +----- ---- +## 🌐 Configurações Padrão -## 💡 Dicas finais + * **Espelho Brasileiro do Pacman**: Para garantir downloads mais rápidos, o `pacman.conf` é configurado por padrão para utilizar o espelho `br.mirrors.cicku.me`. + * **Pacotes Base**: A imagem (`Containerfile.base`) inclui um sistema funcional com Plasma Desktop (KDE), ferramentas de containerização (Podman, Distrobox), Pipewire para áudio e outros utilitários essenciais. -* Sempre use `raglinux.sh` para instalação e upgrades. -* Para instalar apps de forma segura, utilize **containers ou flatpak**. -* Lembre-se que `/` é imutável; alterações diretas fora do OSTree não persistem. - ---- +----- ### Autor Gabriel Aguiar Rocha – [GitHub](https://github.com/gabrielrocha) - ---- - -``` - ---- - -Se você quiser, posso criar uma **versão ainda mais detalhada**, incluindo **passo-a-passo de todo o build**, **comandos do Podman e OSTree**, e **prints de erros comuns e suas soluções**, para servir como documentação completa para qualquer usuário do RAGLinux. - -Quer que eu faça essa versão expandida? -``` From d93b19430cb09721c9ee0435c5b64756ecebf5d2 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:12:33 -0400 Subject: [PATCH 07/12] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 801cd76..3009002 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ----- -# RAGLinux +# RAGostree-utility + **RAGLinux** é um sistema operacional baseado em **Arch Linux** com uma abordagem moderna e robusta: um sistema de arquivos raiz **imutável**, gerenciado de forma atômica pelo **OSTree** e construído com a flexibilidade do **Podman**. From 918ff1395e9898880a4e29b85110b34cdc226fe6 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:49:43 -0400 Subject: [PATCH 08/12] Delete ostree.sh --- ostree.sh | 369 ------------------------------------------------------ 1 file changed, 369 deletions(-) delete mode 100755 ostree.sh diff --git a/ostree.sh b/ostree.sh deleted file mode 100755 index b580f01..0000000 --- a/ostree.sh +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/env bash -set -o errexit # Sai se houver erro -set -o nounset # Erro se usar variável não definida - -# ======================================================== -# [AMBIENTE]: DEFINIÇÃO DE OPÇÕES PADRÃO -# ======================================================== -function AMBIENTE_DEFINIR_OPCOES { - if [[ ${CLI_SILENCIOSO:-} != 1 ]]; then - set -o xtrace # Mostra os comandos sendo executados - fi - - if [[ ! -d '/ostree' ]]; then - # Não mexer nos discos se o sistema já estiver iniciado - declare -g DISCO_DESTINO=${DISCO_DESTINO:="/dev/disk/by-id/${DISCO_SCSI}"} - declare -g PARTICAO_BOOT=${PARTICAO_BOOT:="${DISCO_DESTINO}-part1"} - declare -g PARTICAO_ROOT=${PARTICAO_ROOT:="${DISCO_DESTINO}-part2"} - declare -g MONTAGEM_TEMP=${MONTAGEM_TEMP:='/tmp/chroot'} - fi - - declare -g MONTAGEM_TEMP=${MONTAGEM_TEMP:='/'} - declare -g ROOTFS_TEMP=${ROOTFS_TEMP:='/tmp/rootfs'} - declare -g ARG_KERNEL=${ARG_KERNEL:='rootflags=subvol=@ rootfstype=btrfs'} - declare -g LABEL_BOOT=${LABEL_BOOT:='SYS_BOOT'} - declare -g LABEL_ROOT=${LABEL_ROOT:='SYS_ROOT'} - declare -g OPT_NOMERGE=${OPT_NOMERGE='--no-merge'} - declare -g REPO_NOME=${REPO_NOME:='raglinux'} - - if [[ -n ${FUSO_HORARIO:-} ]]; then - timedatectl set-timezone ${FUSO_HORARIO} - timedatectl set-ntp 1 - fi - declare -g FUSO_HORARIO=${FUSO_HORARIO:='America/Sao_Paulo'} - declare -g TECLADO=${TECLADO:='br-abnt2'} - - declare -g ARQUIVO_CONTAINER=${ARQUIVO_CONTAINER:="${0%/*}/Containerfile.raglinux:ostree/base"} - declare -g SEM_CACHE_PODMAN=${SEM_CACHE_PODMAN:='0'} - declare -g SEM_CACHE_PACMAN=${SEM_CACHE_PACMAN:='0'} -} - -# ======================================================== -# [AMBIENTE]: VERIFICA OSTREE LOCAL -# ======================================================== -function AMBIENTE_VERIFICAR { - if [[ ! -d '/ostree' ]]; then - printf >&2 '\e[31m%s\e[0m\n' 'OSTree não encontrado em: /ostree' - return 1 - fi -} - -# ======================================================== -# [AMBIENTE]: INSTALAR DEPENDÊNCIAS -# ======================================================== -function AMBIENTE_INSTALAR_DEPENDENCIAS { - # Ignora em OSTree (filesystem read-only) - if ! AMBIENTE_VERIFICAR 2>/dev/null; then - pacman --noconfirm --sync --needed "$@" - fi -} - -# ======================================================== -# [DISCO]: CRIAR PARTIÇÕES GPT+UEFI -# ======================================================== -function DISCO_CRIAR_LAYOUT { - AMBIENTE_INSTALAR_DEPENDENCIAS parted - mkdir -p ${MONTAGEM_TEMP} - lsblk --noheadings --output='MOUNTPOINTS' | grep -w ${MONTAGEM_TEMP} | xargs -r umount --lazy --verbose - - if [[ -b "${PARTICAO_BOOT}" && -b "${PARTICAO_ROOT}" ]]; then - echo "Partições já existem, pulando criação..." - return 0 - fi - - parted -a optimal -s ${DISCO_DESTINO} -- \ - mklabel gpt \ - mkpart ${LABEL_BOOT} fat32 0% 257MiB \ - set 1 esp on \ - mkpart ${LABEL_ROOT} btrfs 257MiB 100% -} - -# ======================================================== -# [DISCO]: FORMATAR PARTIÇÕES -# ======================================================== -function DISCO_FORMATAR { - AMBIENTE_INSTALAR_DEPENDENCIAS dosfstools btrfs-progs - mkfs.vfat -n ${LABEL_BOOT} -F 32 ${PARTICAO_BOOT} - mkfs.btrfs -L ${LABEL_ROOT} -f ${PARTICAO_ROOT} -} - -# ======================================================== -# [DISCO]: MONTAR E CRIAR SUBVOLUMES -# ======================================================== -function DISCO_MONTAR { - mount ${PARTICAO_ROOT} ${MONTAGEM_TEMP} - - btrfs subvolume create ${MONTAGEM_TEMP}/@ - btrfs subvolume create ${MONTAGEM_TEMP}/@home - btrfs subvolume create ${MONTAGEM_TEMP}/@var - btrfs subvolume create ${MONTAGEM_TEMP}/@ostree - - umount ${MONTAGEM_TEMP} - mount -o subvol=@ ${PARTICAO_ROOT} ${MONTAGEM_TEMP} - - mkdir -p ${MONTAGEM_TEMP}/{home,var,ostree} - mount -o subvol=@home ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/home - mount -o subvol=@var ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/var - mount -o subvol=@ostree ${PARTICAO_ROOT} ${MONTAGEM_TEMP}/ostree - - mount --mkdir ${PARTICAO_BOOT} ${MONTAGEM_TEMP}/boot/efi -} - -# ======================================================== -# [OSTREE]: INICIALIZAÇÃO DO REPOSITÓRIO -# ======================================================== -function OSTREE_CRIA_REPO { - AMBIENTE_INSTALAR_DEPENDENCIAS ostree which - ostree admin init-fs --sysroot="${MONTAGEM_TEMP}" --modern ${MONTAGEM_TEMP} - ostree admin stateroot-init --sysroot="${MONTAGEM_TEMP}" ${REPO_NOME} - ostree init --repo="${MONTAGEM_TEMP}/ostree/repo" --mode='bare' - ostree config --repo="${MONTAGEM_TEMP}/ostree/repo" set sysroot.bootprefix 1 -} - -# ======================================================== -# [OSTREE]: CRIAR ROOTFS COM PODMAN -# ======================================================== -function OSTREE_CRIA_ROOTFS { - if [[ $(df --output=fstype / | tail --lines 1) = 'overlay' ]]; then - AMBIENTE_INSTALAR_DEPENDENCIAS fuse-overlayfs - declare -x TMPDIR='/tmp/podman' - local OPT_PODMAN_GLOBAL=( - --root="${TMPDIR}/storage" - --tmpdir="${TMPDIR}/tmp" - ) - fi - - AMBIENTE_INSTALAR_DEPENDENCIAS podman - - if [[ ${SEM_CACHE_PACMAN} == 0 ]]; then - mkdir -p "${TMPDIR:-}/var/cache/pacman" - local OPT_PODMAN_BUILD=( - --volume="${TMPDIR:-}/var/cache/pacman:${TMPDIR:-}/var/cache/pacman" - ) - fi - - if [[ ${SEM_CACHE_PODMAN} == 1 ]]; then - local OPT_PODMAN_BUILD=( - ${OPT_PODMAN_BUILD[@]} - --no-cache='1' - ) - fi - - for TARGET in ${ARQUIVO_CONTAINER//,/ }; do - local IMG=${TARGET%:*} - local TAG=${TARGET#*:} - podman ${OPT_PODMAN_GLOBAL[@]} build \ - ${OPT_PODMAN_BUILD[@]} \ - --file="${IMG}" \ - --tag="${TAG}" \ - --cap-add='SYS_ADMIN' \ - --build-arg="LABEL_BOOT=${LABEL_BOOT}" \ - --build-arg="LABEL_ROOT=${LABEL_ROOT}" \ - --build-arg="FUSO_HORARIO=${FUSO_HORARIO}" \ - --build-arg="TECLADO=${TECLADO}" \ - --pull='newer' - done - - rm -rf ${ROOTFS_TEMP} - mkdir -p ${ROOTFS_TEMP} - podman ${OPT_PODMAN_GLOBAL[@]} export $(podman ${OPT_PODMAN_GLOBAL[@]} create ${TAG} bash) | tar -xC ${ROOTFS_TEMP} -} - -# ======================================================== -# [OSTREE]: AJUSTAR ESTRUTURA DE DIRETÓRIOS -# ======================================================== -function OSTREE_AJUSTAR_LAYOUT { - mv ${ROOTFS_TEMP}/etc ${ROOTFS_TEMP}/usr/ - - rm -r ${ROOTFS_TEMP}/home - ln -s var/home ${ROOTFS_TEMP}/home - - rm -r ${ROOTFS_TEMP}/mnt - ln -s var/mnt ${ROOTFS_TEMP}/mnt - - rm -r ${ROOTFS_TEMP}/opt - ln -s var/opt ${ROOTFS_TEMP}/opt - - rm -r ${ROOTFS_TEMP}/root - ln -s var/roothome ${ROOTFS_TEMP}/root - - rm -r ${ROOTFS_TEMP}/srv - ln -s var/srv ${ROOTFS_TEMP}/srv - - mkdir ${ROOTFS_TEMP}/sysroot - ln -s sysroot/ostree ${ROOTFS_TEMP}/ostree - - rm -r ${ROOTFS_TEMP}/usr/local - ln -s ../var/usrlocal ${ROOTFS_TEMP}/usr/local - - printf >&1 '%s\n' 'Criando tmpfiles' - cat <> ${ROOTFS_TEMP}/usr/lib/tmpfiles.d/ostree-0-integracao.conf -d /var/home 0755 root root - -d /var/lib 0755 root root - -d /var/log/journal 0755 root root - -d /var/mnt 0755 root root - -d /var/opt 0755 root root - -d /var/roothome 0700 root root - -d /var/srv 0755 root root - -d /var/usrlocal 0755 root root - -d /var/usrlocal/bin 0755 root root - -d /var/usrlocal/etc 0755 root root - -d /var/usrlocal/games 0755 root root - -d /var/usrlocal/include 0755 root root - -d /var/usrlocal/lib 0755 root root - -d /var/usrlocal/man 0755 root root - -d /var/usrlocal/sbin 0755 root root - -d /var/usrlocal/share 0755 root root - -d /var/usrlocal/src 0755 root root - -d /run/media 0755 root root - -EOF - - mv ${ROOTFS_TEMP}/var/lib/pacman ${ROOTFS_TEMP}/usr/lib/ - sed -i \ - -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ - -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ - ${ROOTFS_TEMP}/usr/etc/pacman.conf - - mkdir ${ROOTFS_TEMP}/usr/lib/pacmanlocal - rm -r ${ROOTFS_TEMP}/var/* -} - -# ======================================================== -# [OSTREE]: CRIAR COMMIT -# ======================================================== -function OSTREE_DEPLOY { - ostree commit --repo="${MONTAGEM_TEMP}/ostree/repo" --branch="${REPO_NOME}/latest" --tree=dir="${ROOTFS_TEMP}" - ostree admin deploy --sysroot="${MONTAGEM_TEMP}" --karg="root=LABEL=${LABEL_ROOT} rw ${ARG_KERNEL}" --os="${REPO_NOME}" ${OPT_NOMERGE} --retain ${REPO_NOME}/latest -} - -# ======================================================== -# [OSTREE]: REVER COMMIT -# ======================================================== -function OSTREE_REVER { - ostree admin undeploy --sysroot="${MONTAGEM_TEMP}" 0 -} - -# ======================================================== -# [BOOTLOADER]: CONFIGURAR GRUB EFI -# ======================================================== -function BOOTLOADER_CONFIG { - grub-install --target='x86_64-efi' --efi-directory="${MONTAGEM_TEMP}/boot/efi" --boot-directory="${MONTAGEM_TEMP}/boot/efi/EFI" --bootloader-id="${REPO_NOME}" --removable ${PARTICAO_BOOT} - - local CAMINHO_SYS=$(ls -d ${MONTAGEM_TEMP}/ostree/deploy/${REPO_NOME}/deploy/* | head -n 1) - - rm -rfv ${CAMINHO_SYS}/boot/* - mount --mkdir --rbind ${MONTAGEM_TEMP}/boot ${CAMINHO_SYS}/boot - mount --mkdir --rbind ${MONTAGEM_TEMP}/ostree ${CAMINHO_SYS}/sysroot/ostree - - for i in /dev /proc /sys; do mount -o bind $i ${CAMINHO_SYS}${i}; done - chroot ${CAMINHO_SYS} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' - - umount --recursive ${MONTAGEM_TEMP} -} - -# ======================================================== -# [CLI]: INTERPRETAÇÃO DE ARGUMENTOS -# ======================================================== -function CLI_EXECUTAR { - CLI_ARGS=$(getopt \ - --alternative \ - --options='b:,c:,d:,f:,k:,t:,m::,n::,q::' \ - --longoptions='base-os:,cmdline:,dev:,file:,keymap:,time:,merge::,no-cache::,no-pacman-cache::,no-podman-cache::,quiet::' \ - --name="${0##*/}" \ - -- "${@}" - ) - - eval set -- "${CLI_ARGS}" - - while [[ ${#} > 0 ]]; do - CLI_ARG=${1:-} - CLI_VAL=${2:-} - - case ${CLI_ARG} in - '-b' | '--base-os') REPO_NOME=${CLI_VAL} ;; - '-c' | '--cmdline') ARG_KERNEL=${CLI_VAL} ;; - '-d' | '--dev') DISCO_SCSI=${CLI_VAL} ;; - '-f' | '--file') ARQUIVO_CONTAINER=${CLI_VAL} ;; - '-k' | '--keymap') TECLADO=${CLI_VAL} ;; - '-t' | '--time') FUSO_HORARIO=${CLI_VAL} ;; - esac - - [[ ${CLI_VAL@L} == 'true' ]] && CLI_VAL='1' - [[ ${CLI_VAL@L} == 'false' ]] && CLI_VAL='0' - case ${CLI_ARG} in - '-m' | '--merge') OPT_NOMERGE=${CLI_VAL:-} ;; - '-n' | '--no-cache') SEM_CACHE_PACMAN=${CLI_VAL:-1}; SEM_CACHE_PODMAN=${CLI_VAL:-1} ;; - '--no-pacman-cache') SEM_CACHE_PACMAN=${CLI_VAL:-1} ;; - '--no-podman-cache') SEM_CACHE_PODMAN=${CLI_VAL:-1} ;; - '-q' | '--quiet') CLI_SILENCIOSO=${CLI_VAL:-1} ;; - esac - - if [[ ${CLI_ARG} == '--' ]]; then - case ${CLI_VAL} in - 'install') - AMBIENTE_DEFINIR_OPCOES - DISCO_CRIAR_LAYOUT - DISCO_FORMATAR - DISCO_MONTAR - OSTREE_CRIA_REPO - OSTREE_CRIA_ROOTFS - OSTREE_AJUSTAR_LAYOUT - OSTREE_DEPLOY - BOOTLOADER_CONFIG - ;; - 'upgrade') - AMBIENTE_VERIFICAR || exit $? - AMBIENTE_DEFINIR_OPCOES - OSTREE_CRIA_ROOTFS - OSTREE_AJUSTAR_LAYOUT - OSTREE_DEPLOY - ;; - 'revert') - AMBIENTE_VERIFICAR || exit $? - AMBIENTE_DEFINIR_OPCOES - OSTREE_REVER - ;; - *) - if [[ $(type -t ${CLI_VAL}) == 'function' ]]; then - AMBIENTE_DEFINIR_OPCOES - ${CLI_VAL} - fi - ;;& - * | 'help') - local AJUDA=( - 'Uso:' - " ${0##*/} [opcoes]" - 'Comandos:' - ' install : (Criar deploy) : Particiona, formata e inicializa OSTree' - ' upgrade : (Atualizar deploy) : Cria novo commit OSTree' - ' revert : (Reverter commit) : Restaura versão 0' - 'Opções:' - ' -b, --base-os string : (install/upgrade) : Nome do OS base. Padrão: raglinux' - ' -c, --cmdline string : (install/upgrade) : Argumentos do kernel' - ' -d, --dev string : (install ) : ID do disco para instalação' - ' -f, --file stringArray : (install/upgrade) : Containerfile(s)' - ' -k, --keymap string : (install/upgrade) : Layout teclado' - ' -t, --time string : (install/upgrade) : Fuso horário host' - 'Switches:' - ' -m, --merge : ( upgrade) : Manter /etc existente' - ' -n, --no-cache : (install/upgrade) : Ignora cache' - ' --no-pacman-cache : (install/upgrade) : Ignora cache Pacman' - ' --no-podman-cache : (install/upgrade) : Ignora cache Podman' - ' -q, --quiet : (install/upgrade) : Reduz verbosidade' - ) - printf >&1 '%s\n' "${AJUDA[@]}" - - if [[ ${CLI_VAL} != 'help' && -n ${CLI_VAL} ]]; then - printf >&2 '\n%s\n' "${0##*/}: comando desconhecido '${CLI_VAL}'" - exit 127 - fi - ;; - esac - break - fi - - shift 2 - done -} - -CLI_EXECUTAR "${@}" From cc4689542678c068cb04f89fda0e3346ecd4d62a Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:49:54 -0400 Subject: [PATCH 09/12] Delete archlinux directory --- archlinux/Containerfile.base | 39 ------------------------------------ 1 file changed, 39 deletions(-) delete mode 100644 archlinux/Containerfile.base diff --git a/archlinux/Containerfile.base b/archlinux/Containerfile.base deleted file mode 100644 index c0be327..0000000 --- a/archlinux/Containerfile.base +++ /dev/null @@ -1,39 +0,0 @@ -# | -# | ROOTFS -# | - -FROM docker.io/archlinux/archlinux:latest AS rootfs - -RUN curl https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/main/pacman.conf -o /etc/pacman.conf \ - && pacman --noconfirm --sync --needed --refresh archlinux-keyring - -RUN pacman --noconfirm --sync --needed arch-install-scripts \ - && pacstrap -K -P /mnt \ - base base-devel linux linux-firmware ostree btrfs-progs nano git \ - plasma-desktop konsole dolphin plasma-wayland-session sddm \ - cockpit fwupd \ - pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber \ - bluez bluez-utils \ - gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav ffmpeg \ - podman distrobox \ - bazaar buildah skopeo just \ - networkmanager fastfetch flatpak \ - && cp -av /etc/pacman.d/ /mnt/etc/ - -# | -# | BASE -# | - -FROM scratch AS base -COPY --from=rootfs /mnt / - -# Configurações do sistema RAGlinux -ARG SYSTEM_OPT_TIMEZONE="America/Cuiaba" -ARG SYSTEM_OPT_KEYMAP="br-abnt2" - -RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime \ - && echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf \ - && echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \ - && echo 'pt_BR.UTF-8 UTF-8' >> /etc/locale.gen \ - && locale-gen \ - && echo "RAGlinux" > /etc/hostname From 82f0c81483708c0c9c09ea14ef5fac35b7ea7820 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 16:50:57 -0400 Subject: [PATCH 10/12] Update post-install.sh --- post-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post-install.sh b/post-install.sh index c48d39f..e0a141a 100755 --- a/post-install.sh +++ b/post-install.sh @@ -6,8 +6,8 @@ systemctl enable cockpit.socket systemctl enable fwupd # Configurar usuário padrão -useradd -m -G wheel -s /bin/bash rag -echo "rag:200519" | chpasswd +useradd -m -G wheel -s /bin/bash user +echo "user:user" | chpasswd # Configurações específicas do Plasma echo "[General]" > /etc/sddm.conf From 0230bebea2f4b474ce237139f41ec0f0fab9eef2 Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 23:03:55 -0400 Subject: [PATCH 11/12] Update Containerfile.base --- Containerfile.base | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/Containerfile.base b/Containerfile.base index 2d4865d..a21c3aa 100644 --- a/Containerfile.base +++ b/Containerfile.base @@ -2,43 +2,36 @@ # | ROOTFS # | +# Build a clean system in /mnt to avoid missing files from NoExtract option in upstream FROM docker.io/archlinux/archlinux:latest AS rootfs +# Build in chroot to correctly execute hooks, this uses host's Pacman RUN curl https://gitlab.archlinux.org/archlinux/packaging/packages/pacman/-/raw/main/pacman.conf -o /etc/pacman.conf \ && pacman --noconfirm --sync --needed --refresh archlinux-keyring -# Atualiza pacman.conf com o mirror brasileiro -RUN echo "Server = https://br.mirrors.cicku.me/archlinux/\$repo/os/\$arch" > /etc/pacman.d/mirrorlist \ - && pacman -Sy --noconfirm archlinux-keyring - - +# Perform a clean system installation with latest Arch Linux packages in chroot to correctly execute hooks, this uses host's Pacman RUN pacman --noconfirm --sync --needed arch-install-scripts \ - && pacstrap -K -P /mnt \ - base base-devel linux linux-firmware ostree btrfs-progs nano git \ - plasma-desktop konsole dolphin plasma-workspace sddm \ - cockpit fwupd \ - pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber \ - bluez bluez-utils \ - gst-plugins-good gst-plugins-bad gst-plugins-ugly gst-libav ffmpeg \ - podman distrobox \ - bzr buildah skopeo just \ - networkmanager fastfetch flatpak \ + && pacstrap -K -P /mnt base base-devel linux-firmware fwupd \ && cp -av /etc/pacman.d/ /mnt/etc/ # | # | BASE # | +# Reusable base template FROM scratch AS base COPY --from=rootfs /mnt / -# Configurações do sistema RAGlinux -ARG SYSTEM_OPT_TIMEZONE="America/Cuiaba" -ARG SYSTEM_OPT_KEYMAP="br-abnt2" +# Clock +# Define o fuso horário para o Brasil (Mato Grosso) +RUN ln --symbolic --force /usr/share/zoneinfo/America/Cuiaba /etc/localtime + +# Keymap hook +# Define o layout do teclado para o padrão brasileiro ABNT2 +RUN echo "KEYMAP=br-abnt2" > /etc/vconsole.conf -RUN ln --symbolic --force /usr/share/zoneinfo/${SYSTEM_OPT_TIMEZONE} /etc/localtime \ - && echo "KEYMAP=${SYSTEM_OPT_KEYMAP}" > /etc/vconsole.conf \ - && echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \ - && echo 'pt_BR.UTF-8 UTF-8' >> /etc/locale.gen \ - && locale-gen \ - && echo "RAGlinux" > /etc/hostname +# Language +# Define o idioma e local para Português do Brasil +RUN echo 'LANG=pt_BR.UTF-8' > /etc/locale.conf \ + && echo 'pt_BR.UTF-8 UTF-8' > /etc/locale.gen \ + && locale-gen From 0dd71a6ef7fa3c74c8a769dd45db500e0d7aa55f Mon Sep 17 00:00:00 2001 From: gabriel aguiar rocha Date: Sun, 31 Aug 2025 23:07:14 -0400 Subject: [PATCH 12/12] Update raglinux.sh --- raglinux.sh | 359 ++++++---------------------------------------------- 1 file changed, 37 insertions(+), 322 deletions(-) diff --git a/raglinux.sh b/raglinux.sh index 93fbfa8..ac7d2fb 100755 --- a/raglinux.sh +++ b/raglinux.sh @@ -18,25 +18,21 @@ function ENV_CREATE_OPTS { declare -g OSTREE_SYS_ROOT=${OSTREE_SYS_ROOT:='/'} declare -g OSTREE_SYS_TREE=${OSTREE_SYS_TREE:='/tmp/rootfs'} - declare -g OSTREE_SYS_KARG=${OSTREE_SYS_KARG:='rootflags=subvol=@ rootfstype=btrfs'} - declare -g OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL:='ARCHISO_EFI'} - declare -g OSTREE_SYS_ROOT_LABEL=${OSTREE_SYS_ROOT_LABEL:='RAGLinux'} + declare -g OSTREE_SYS_KARG=${OSTREE_SYS_KARG:=''} + declare -g OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL:='SYS_BOOT'} + declare -g OSTREE_SYS_ROOT_LABEL=${OSTREE_SYS_ROOT_LABEL:='SYS_ROOT'} declare -g OSTREE_OPT_NOMERGE=${OSTREE_OPT_NOMERGE='--no-merge'} - declare -g OSTREE_REP_NAME=${OSTREE_REP_NAME:='raglinux'} + declare -g OSTREE_REP_NAME=${OSTREE_REP_NAME:='archlinux'} - if [[ -n ${SYSTEM_OPT_TIMEZONE:-} ]]; then - # Do not modify host's time unless explicitly specified - timedatectl set-timezone ${SYSTEM_OPT_TIMEZONE} - timedatectl set-ntp 1 - fi - declare -g SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE:='America/Cuiaba'} - declare -g SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP:='br-abnt2'} + # Timezone and Keymap are now hardcoded in Containerfile.base + # and no longer need to be set here. - declare -g PODMAN_OPT_BUILDFILE=${PODMAN_OPT_BUILDFILE:="${0%/*}/Containerfile.base:ostree/base"} + declare -g PODMAN_OPT_BUILDFILE=${PODMAN_OPT_BUILDFILE:="${0%/*}/Containerfile.base:ostree/base","${0%/*}/Containerfile.host.example:ostree/host"} declare -g PODMAN_OPT_NOCACHE=${PODMAN_OPT_NOCACHE:='0'} declare -g PACMAN_OPT_NOCACHE=${PACMAN_OPT_NOCACHE:='0'} } + # [ENVIRONMENT]: OSTREE CHECK function ENV_VERIFY_LOCAL { if [[ ! -d '/ostree' ]]; then @@ -53,45 +49,40 @@ function ENV_CREATE_DEPS { fi } -# [DISK]: PARTITIONING (GPT+UEFI) - SKIP AS PARTITIONS ALREADY EXIST +# [DISK]: PARTITIONING (GPT+UEFI) for Btrfs function DISK_CREATE_LAYOUT { - echo "Partições já existem, pulando criação..." - return 0 + ENV_CREATE_DEPS parted + mkdir -p ${OSTREE_SYS_ROOT} + lsblk --noheadings --output='MOUNTPOINTS' | grep -w ${OSTREE_SYS_ROOT} | xargs -r umount --lazy --verbose + parted -a optimal -s ${OSTREE_DEV_DISK} -- \ + mklabel gpt \ + mkpart ${OSTREE_SYS_BOOT_LABEL} fat32 0% 257MiB \ + set 1 esp on \ + mkpart ${OSTREE_SYS_ROOT_LABEL} btrfs 257MiB 100% } -# [DISK]: FILESYSTEM (ESP+BTRFS) - SKIP AS FILESYSTEMS ALREADY EXIST +# [DISK]: FILESYSTEM (ESP+Btrfs) with Subvolumes function DISK_CREATE_FORMAT { - echo "Sistemas de arquivo já existem, pulando formatação..." - return 0 -} + ENV_CREATE_DEPS dosfstools btrfs-progs + mkfs.vfat -n ${OSTREE_SYS_BOOT_LABEL} -F 32 ${OSTREE_DEV_BOOT} + mkfs.btrfs -L ${OSTREE_SYS_ROOT_LABEL} -f ${OSTREE_DEV_ROOT} -# [DISK]: BUILD DIRECTORY -function DISK_CREATE_MOUNTS { - # Criar diretório de montagem se não existir - mkdir -p ${OSTREE_SYS_ROOT} - - # Montar partição root temporariamente para criar subvolumes + # Create Btrfs subvolumes for root and home mount ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} - - # Criar subvolumes BTRFS - btrfs subvolume create ${OSTREE_SYS_ROOT}/@ || true - btrfs subvolume create ${OSTREE_SYS_ROOT}/@home || true - btrfs subvolume create ${OSTREE_SYS_ROOT}/@var || true - btrfs subvolume create ${OSTREE_SYS_ROOT}/@ostree || true - - # Desmontar e remontar com subvolumes + btrfs subvolume create ${OSTREE_SYS_ROOT}/@ + btrfs subvolume create ${OSTREE_SYS_ROOT}/@home umount ${OSTREE_SYS_ROOT} - mount -o subvol=@ ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} - - # Criar diretórios e montar subvolumes - mkdir -p ${OSTREE_SYS_ROOT}/{home,var,ostree} - mount -o subvol=@home ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/home - mount -o subvol=@var ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/var - mount -o subvol=@ostree ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/ostree - - # Montar partição EFI - mkdir -p ${OSTREE_SYS_ROOT}/boot/efi - mount ${OSTREE_DEV_BOOT} ${OSTREE_SYS_ROOT}/boot/efi +} + +# [DISK]: BUILD DIRECTORY with Btrfs Subvolumes +function DISK_CREATE_MOUNTS { + # Mount root subvolume + mount -o compress=zstd,subvol=@ ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT} + # Mount boot partition + mount --mkdir ${OSTREE_DEV_BOOT} ${OSTREE_SYS_ROOT}/boot/efi + # Mount home subvolume + mkdir -p ${OSTREE_SYS_ROOT}/home + mount -o compress=zstd,subvol=@home ${OSTREE_DEV_ROOT} ${OSTREE_SYS_ROOT}/home } # [OSTREE]: FIRST INITIALIZATION @@ -108,7 +99,7 @@ function OSTREE_CREATE_ROOTFS { # Add support for overlay storage driver in LiveCD if [[ $(df --output=fstype / | tail --lines 1) = 'overlay' ]]; then ENV_CREATE_DEPS fuse-overlayfs - declare -x TMPDIR='/mnt/podman' + declare -x TMPDIR='/tmp/podman' local PODMAN_OPT_GLOBAL=( --root="${TMPDIR}/storage" --tmpdir="${TMPDIR}/tmp" @@ -118,280 +109,4 @@ function OSTREE_CREATE_ROOTFS { # Install Podman ENV_CREATE_DEPS podman - # Copy Pacman package cache into /var by default (to avoid duplication) - if [[ ${PACMAN_OPT_NOCACHE} == 0 ]]; then - mkdir -p "${TMPDIR:-}/var/cache/pacman" - local PODMAN_OPT_BUILD=( - --volume="${TMPDIR:-}/var/cache/pacman:${TMPDIR:-}/var/cache/pacman" - ) - fi - - # Skip Podman layer cache if requested - if [[ ${PODMAN_OPT_NOCACHE} == 1 ]]; then - local PODMAN_OPT_BUILD=( - ${PODMAN_OPT_BUILD[@]} - --no-cache='1' - ) - fi - - # Podman: create rootfs from multiple Containerfiles - for TARGET in ${PODMAN_OPT_BUILDFILE//,/ }; do - local PODMAN_OPT_IMG=(${TARGET%:*}) - local PODMAN_OPT_TAG=(${TARGET#*:}) - podman ${PODMAN_OPT_GLOBAL[@]} build \ - ${PODMAN_OPT_BUILD[@]} \ - --file="${PODMAN_OPT_IMG}" \ - --tag="${PODMAN_OPT_TAG}" \ - --cap-add='SYS_ADMIN' \ - --build-arg="OSTREE_SYS_BOOT_LABEL=${OSTREE_SYS_BOOT_LABEL}" \ - --build-arg="OSTREE_SYS_ROOT_LabEL=${OSTREE_SYS_ROOT_LABEL}" \ - --build-arg="SYSTEM_OPT_TIMEZONE=${SYSTEM_OPT_TIMEZONE}" \ - --build-arg="SYSTEM_OPT_KEYMAP=${SYSTEM_OPT_KEYMAP}" \ - --pull='newer' - done - - # Ostreeify: retrieve rootfs (workaround: `podman build --output local` doesn't preserve ownership) - rm -rf ${OSTREE_SYS_TREE} - mkdir -p ${OSTREE_SYS_TREE} - podman ${PODMAN_OPT_GLOBAL[@]} export $(podman ${PODMAN_OPT_GLOBAL[@]} create ${PODMAN_OPT_TAG} bash) | tar -xC ${OSTREE_SYS_TREE} -} - -# [OSTREE]: DIRECTORY STRUCTURE -function OSTREE_CREATE_LAYOUT { - # Doing it here allows the container to be runnable/debuggable and Containerfile reusable - mv ${OSTREE_SYS_TREE}/etc ${OSTREE_SYS_TREE}/usr/ - - rm -r ${OSTREE_SYS_TREE}/home - ln -s var/home ${OSTREE_SYS_TREE}/home - - rm -r ${OSTREE_SYS_TREE}/mnt - ln -s var/mnt ${OSTREE_SYS_TREE}/mnt - - rm -r ${OSTREE_SYS_TREE}/opt - ln -s var/opt ${OSTREE_SYS_TREE}/opt - - rm -r ${OSTREE_SYS_TREE}/root - ln -s var/roothome ${OSTREE_SYS_TREE}/root - - rm -r ${OSTREE_SYS_TREE}/srv - ln -s var/srv ${OSTREE_SYS_TREE}/srv - - mkdir ${OSTREE_SYS_TREE}/sysroot - ln -s sysroot/ostree ${OSTREE_SYS_TREE}/ostree - - rm -r ${OSTREE_SYS_TREE}/usr/local - ln -s ../var/usrlocal ${OSTREE_SYS_TREE}/usr/local - - printf >&1 '%s\n' 'Creating tmpfiles' - echo 'd /var/home 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/log/journal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/mnt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/opt 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/roothome 0700 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/srv 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/bin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/etc 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/games 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/include 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/lib 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/man 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/sbin 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/share 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /var/usrlocal/src 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - echo 'd /run/media 0755 root root -' >> ${OSTREE_SYS_TREE}/usr/lib/tmpfiles.d/ostree-0-integration.conf - - # Only retain information about Pacman packages in new rootfs - mv ${OSTREE_SYS_TREE}/var/lib/pacman ${OSTREE_SYS_TREE}/usr/lib/ - sed -i \ - -e 's|^#\(DBPath\s*=\s*\).*|\1/usr/lib/pacman|g' \ - -e 's|^#\(IgnoreGroup\s*=\s*\).*|\1modified|g' \ - ${OSTREE_SYS_TREE}/usr/etc/pacman.conf - - # Allow Pacman to store update notice id during unlock mode - mkdir ${OSTREE_SYS_TREE}/usr/lib/pacmanlocal - - # OSTree mounts /ostree/deploy/${OSTREE_REP_NAME}/var to /var - rm -r ${OSTREE_SYS_TREE}/var/* -} - -# [OSTREE]: CREATE COMMIT -function OSTREE_DEPLOY_IMAGE { - # Update repository and boot entries in GRUB2 - ostree commit --repo="${OSTREE_SYS_ROOT}/ostree/repo" --branch="${OSTREE_REP_NAME}/latest" --tree=dir="${OSTREE_SYS_TREE}" - ostree admin deploy --sysroot="${OSTREE_SYS_ROOT}" --karg="root=LABEL=${OSTREE_SYS_ROOT_LABEL} rw ${OSTREE_SYS_KARG}" --os="${OSTREE_REP_NAME}" ${OSTREE_OPT_NOMERGE} --retain ${OSTREE_REP_NAME}/latest -} - -# [OSTREE]: UNDO COMMIT -function OSTREE_REVERT_IMAGE { - ostree admin undeploy --sysroot="${OSTREE_SYS_ROOT}" 0 -} - -# [BOOTLOADER]: FIRST BOOT -function BOOTLOADER_CREATE { - grub-install --target='x86_64-efi' --efi-directory="${OSTREE_SYS_ROOT}/boot/efi" --boot-directory="${OSTREE_SYS_ROOT}/boot/efi/EFI" --bootloader-id="${OSTREE_REP_NAME}" --removable ${OSTREE_DEV_BOOT} - - local OSTREE_SYS_PATH=$(ls -d ${OSTREE_SYS_ROOT}/ostree/deploy/${OSTREE_REP_NAME}/deploy/* | head -n 1) - - rm -rfv ${OSTREE_SYS_PATH}/boot/* - mount --mkdir --rbind ${OSTREE_SYS_ROOT}/boot ${OSTREE_SYS_PATH}/boot - mount --mkdir --rbind ${OSTREE_SYS_ROOT}/ostree ${OSTREE_SYS_PATH}/sysroot/ostree - - for i in /dev /proc /sys; do mount -o bind $i ${OSTREE_SYS_PATH}${i}; done - chroot ${OSTREE_SYS_PATH} /bin/bash -c 'grub-mkconfig -o /boot/efi/EFI/grub/grub.cfg' - - umount --recursive ${OSTREE_SYS_ROOT} -} - -# [CLI]: TASK FINECONTROL -function CLI_SETUP { - CLI_ARGS=$(getopt \ - --alternative \ - --options='b:,c:,d:,f:,k:,t:,m::,n::,q::' \ - --longoptions='base-os:,cmdline:,dev:,file:,keymap:,time:,merge::,no-cache::,no-pacman-cache::,no-podman-cache::,quiet::' \ - --name="${0##*/}" \ - -- "${@}" - ) - - # Rewrite "${@}" - eval set -- "${CLI_ARGS}" - - # Arguments - while [[ ${#} > 0 ]]; do - CLI_ARG=${1:-} - CLI_VAL=${2:-} - - # Options - case ${CLI_ARG} in - '-b' | '--base-os') - declare -g OSTREE_REP_NAME=${CLI_VAL} - ;; - - '-c' | '--cmdline') - declare -g OSTREE_SYS_KARG=${CLI_VAL} - ;; - - '-d' | '--dev') - declare -g OSTREE_DEV_SCSI=${CLI_VAL} - ;; - - '-f' | '--file') - declare -g PODMAN_OPT_BUILDFILE=${CLI_VAL} - ;; - - '-k' | '--keymap') - declare -g SYSTEM_OPT_KEYMAP=${CLI_VAL} - ;; - - '-t' | '--time') - declare -g SYSTEM_OPT_TIMEZONE=${CLI_VAL} - ;; - esac - - # Switches - [[ ${CLI_VAL@L} == 'true' ]] && CLI_VAL='1' - [[ ${CLI_VAL@L} == 'false' ]] && CLI_VAL='0' - case ${CLI_ARG} in - '-m' | '--merge') - declare -g OSTREE_OPT_NOMERGE=${CLI_VAL:-} - ;; - - '-n' | '--no-cache') - declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} - declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '--no-pacman-cache') - declare -g PACMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '--no-podman-cache') - declare -g PODMAN_OPT_NOCACHE=${CLI_VAL:-1} - ;; - - '-q' | '--quiet') - declare -g CLI_QUIET=${CLI_VAL:-1} - ;; - esac - - # Commands - if [[ ${CLI_ARG} == '--' ]]; then - case ${CLI_VAL} in - 'install') - ENV_CREATE_OPTS - - DISK_CREATE_LAYOUT - DISK_CREATE_FORMAT - DISK_CREATE_MOUNTS - - OSTREE_CREATE_REPO - OSTREE_CREATE_ROOTFS - OSTREE_CREATE_LAYOUT - OSTREE_DEPLOY_IMAGE - - BOOTLOADER_CREATE - ;; - - 'upgrade') - ENV_VERIFY_LOCAL || exit $? - ENV_CREATE_OPTS - - OSTREE_CREATE_ROOTFS - OSTREE_CREATE_LAYOUT - OSTREE_DEPLOY_IMAGE - ;; - - 'revert') - ENV_VERIFY_LOCAL || exit $? - ENV_CREATE_OPTS - - OSTREE_REVERT_IMAGE - ;; - - *) - if [[ $(type -t ${CLI_VAL}) == 'function' ]]; then - ENV_CREATE_OPTS - ${CLI_VAL} - fi - ;;& - - * | 'help') - local USAGE=( - 'Usage:' - " ${0##*/} [options]" - 'Commands:' - ' install : (Create deployment) : Partitions, formats and initializes a new OSTree repository' - ' upgrade : (Update deployment) : Creates a new OSTree commit' - ' revert : (Update deployment) : Rolls back version 0' - 'Options:' - ' -b, --base-os string : (install/upgrade) : Name of OS to use as a base. Defaults to raglinux' - ' -c, --cmdline string : (install/upgrade) : List of kernel arguments for boot' - ' -d, --dev string : (install ) : Device SCSI (ID-LINK) for new installation' - ' -f, --file stringArray : (install/upgrade) : Containerfile(s) for new deployment' - ' -k, --keymap string : (install/upgrade) : TTY keyboard layout for new deployment' - ' -t, --time string : (install/upgrade) : Update host timezone for new deployment' - 'Switches:' - ' -m, --merge : ( upgrade) : Retain contents of /etc for existing deployment' - ' -n, --no-cache : (install/upgrade) : Skip any cached data (note: implied for first deployment)' - ' --no-pacman-cache : (install/upgrade) : Skip Pacman package cache' - ' --no-podman-cache : (install/upgrade) : Skip Podman layer cache' - ' -q, --quiet : (install/upgrade) : Reduce verbosity' - ) - printf >&1 '%s\n' "${USAGE[@]}" - - if [[ ${CLI_VAL} != 'help' && -n ${CLI_VAL} ]]; then - printf >&2 '\n%s\n' "${0##*/}: unrecognized command '${CLI_VAL}'" - exit 127 - fi - ;; - esac - break - fi - - # Continue to the next argument - shift 2 - done -} - -CLI_SETUP "${@}" + # Copy Pacman package cache into /var by default (