我的设置

我的设置

我正在尝试做这样的事情:如何将 GRUB 重新安装到 EFI 分区?

但是,我不知道如何运行,chroot因为这是一个自动化过程(使用 Ansible,但这并不重要;如果可以在 Bash 中编写脚本,那对我来说就行得通了),所以我遇到了麻烦grub-install

我的设置

运行带有第二块硬盘 ( /dev/sdb) 的 Ubuntu 18.04 系统,其中有两个分区:根分区 ( /dev/sdb2) 安装在 中/mnt/root,EFI 分区 ( /dev/sdb1) 安装在 中/mnt/root/boot/efi。我根据需要将正在运行的系统中的全部内容复制到了这两个分区中。

然后我尝试运行这个来安装 grub 并使第二个硬盘可启动:

grub-install /dev/sdb1 --efi-directory=/mnt/root/boot/efi --boot-directory=/mnt/root/boot --target=x86_64-efi

我还尝试过(另外)重新生成 grub.cfg:

grub-mkconfig -o /mnt/root/boot/grub/grub.cfg

我知道我可能需要弄乱 UUID 并告诉 GRUB 从哪个硬盘启动。目标是取出第二个硬盘并启动它通过它自己在另一台机器上(因此 GRUB 可能首先知道它(hd1),但很有可能它(hd0)在新的机器中。

对此有什么想法吗?

编辑:

我认为 GRUB 确实已成功安装。我进入提示符grub>,并可以从第二个硬盘驱动器手动启动。我想这意味着我只需要一个可行的grub.cfg方法就/etc/fstab可以完成这项工作。

答案1

我终于让它工作了,如下所示(最后有完整的 Ansible 剧本)。

我将原始根分区复制到新的根分区,排除一些特殊的挂载和(更重要的是)/boot目录内容,因此我从一张白纸开始:

rsync -ahPHAXx --delete --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/boot/*,/mnt/*,/media/*,/lost+found/*} / /mnt/root

然后安装grub:

grub-install --efi-directory=/mnt/esp --boot-directory=/mnt/root/boot --removable --target=x86_64-efi

生成 grub 配置:

grub-mkconfig -o /mnt/root/boot/grub/grub.cfg

这不包括稍后使用的vmlinuz图像initrd(假设启动分区为空),因此请将它们复制过来:

rsync -ahPHAXx --exclude="*/" --delete /boot/* /mnt/root/boot

由于 UUID 不同,我需要更新/mnt/root/boot/grub/grub.cfg/mnt/root/etc/fstab,并用新的 UUID 替换旧 UUID 的每个实例。

我还需要编辑 ESP grub.cfg(在 中/mnt/esp/EFI/BOOT/grub.cfg)以查看hd0而不是hd1

我还/dev/sdb从中删除了对这些安装的引用fstab,因此剩下的只是一行用于安装 ESP,以及一行用于安装/

为我完成此操作的整个 Ansible 剧本如下:

---
- hosts: 
  - deploy
  become: yes
  become_method: sudo
  vars:
    device: /dev/sdb
  tasks:
    - name: Unmount
      mount:
        path: "/mnt/{{ item }}"
        state: unmounted
      with_items:
        - esp
        - root

    - name: Delete partitions
      community.general.parted:
        device: "{{ device }}"
        number: "{{ item }}"
        state: absent
      with_items:
        - 1
        - 2

    - name: Create efi partition
      community.general.parted:
        device: "{{ device }}"
        number: 1
        label: gpt
        fs_type: fat32
        name: EFI System Partition
        flags: [ esp, boot ]
        part_start: "1MiB"
        part_end: "513MiB"
        state: present
      register: part

    - debug:
        var: part

    - name: Create root partition
      community.general.parted:
        device: "{{ device }}"
        number: 2
        name: root
        label: gpt # need to repeat the label here, otherwise the first partition gets overwritten
        part_start: "513MiB"
        part_end: "100%"
        state: present

    - name: Make root partition ext4
      filesystem:
        dev: "{{ device }}2"
        fstype: ext4

    - name: Make efi partition fat32
      shell: "mkfs.fat -F32 {{ device }}1"

    - name: "Get UUID for existing root"
      command: blkid -s UUID -o value /dev/sda2
      register: root_uuid
      changed_when: False

    - name: "Get UUID for existing efi"
      command: blkid -s UUID -o value /dev/sda1
      register: efi_uuid
      changed_when: False

    - name: "Get UUID for new root"
      command: blkid -s UUID -o value {{ device }}2
      register: new_root_uuid
      changed_when: False

    - name: "Get UUID for new efi"
      command: blkid -s UUID -o value {{ device }}1
      register: new_efi_uuid
      changed_when: False

    - debug:
        var: efi_uuid.stdout
    - debug:
        var: new_efi_uuid.stdout
    - debug:
        var: root_uuid.stdout
    - debug:
        var: new_root_uuid.stdout

    - name: Mount root from the other device
      mount:
        path: /mnt/root
        src: "{{ device }}2"
        fstype: ext4
        state: mounted

    - name: Mount efi from the other device
      mount:
        path: /mnt/esp
        src: "{{ device }}1"
        fstype: vfat
        state: mounted

    - name: copy root partition over
      shell: rsync -ahPHAXx --delete --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/boot/*,/mnt/*,/media/*,/lost+found/*} / /mnt/root
      args:
       executable: /bin/bash
       
    - name: copy boot images over
      shell: rsync -ahPHAXx --exclude="*/" --delete /boot/* /mnt/root/boot

    - name: install GRUB to make it bootable
      shell: "grub-install --efi-directory=/mnt/esp --boot-directory=/mnt/root/boot --removable --target=x86_64-efi"

    - name: Edit grub.cfg to point to hd0
      replace:
        path: /mnt/esp/EFI/BOOT/grub.cfg
        regexp: hd1
        replace: hd0

    - name: Generate grub.cfg
      shell: "grub-mkconfig -o /mnt/root/boot/grub/grub.cfg"

    - name: Edit UUID in boot/grub/grub.cfg
      replace:
        path: /mnt/root/boot/grub/grub.cfg
        regexp: "{{ root_uuid.stdout }}"
        replace: "{{ new_root_uuid.stdout }}"

    - name: Edit root UUID in etc/fstab
      replace:
        path: /mnt/root/etc/fstab
        regexp: "{{ root_uuid.stdout }}"
        replace: "{{ new_root_uuid.stdout }}"

    - name: Edit ESP UUID in etc/fstab
      replace:
        path: /mnt/root/etc/fstab
        regexp: "{{ efi_uuid.stdout }}"
        replace: "{{ new_efi_uuid.stdout }}"

    - name: Remove /dev/sdb references from fstab
      lineinfile:
        path: /mnt/root/etc/fstab
        state: absent
        regexp: '^/dev/sdb'

满足以下要求:

---
collections:
  - community.general

相关内容