I am trying to do something like this: How can I reinstall GRUB to the EFI partition?

However, I don't see how I can run chroot because it's an automated process (with Ansible, but that shouldn't matter; if this can be scripted in Bash, that'd work for me), so I am having trouble with grub-install.

My setup

Running a Ubuntu 18.04 system with a second hard drive (/dev/sdb) with two partitions: root partition (/dev/sdb2) mounted in /mnt/root, EFI partition (/dev/sdb1) mounted in /mnt/root/boot/efi. I copied everything from the running system to those two partitions as appropriate.

I've then tried to run this to install grub and make the second hard drive bootable:

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

I've also tried (in addition) to regenerate the grub.cfg:

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

I know I probably need to mess with the UUIDs and tell GRUB which HD to boot from. The goal is to take out the second hard drive and boot it by itself in another machine (so GRUB may know it first as (hd1), but chances are it will be (hd0) in the new box.

Any idea on this?


I think GRUB is actually installed successfully. I am thrown into a grub> prompt, and can manually boot from the second hard drive. I guess that means I just need a working grub.cfg and possible /etc/fstab to make this work.

  • Boot drive is always hd0, so often first boot of anything not installed to first drive is an issue. Lets see details, use ppa version with your live installer (2nd option) or any working install, not Boot-Repair ISO: Please copy & paste the pastebin link to the Boot-info summary report ( do not post report), do not run the auto fix till reviewed. help.ubuntu.com/community/Boot-Repair I just install grub to sdb's ESP when installing. Posted work around to manually unmount & mount correct ESP during install #23 & #26 bugs.launchpad.net/ubuntu/+source/ubiquity/+bug/1396379 – oldfred Oct 19 '20 at 23:03
  • are you trying to clone your 18.04 system from drive "X" to drive "Y" and then configure grub on "Y" to make it bootable, so you can remove "Y" and boot it in another PC? – WU-TANG Oct 20 '20 at 2:46
  • @WU-TANG yes, exactly – godfool Oct 20 '20 at 12:26
  • @oldfred I will check out Boot Repair and see if it solves my problem, thanks! – godfool Oct 20 '20 at 12:29
  • There are much simpler ways to have done this... there are applications, there are even commands that can be used for cloning... With that said, if you get it working your own way, it builds experience. But if you end up needing other options, make it known. – WU-TANG Oct 20 '20 at 14:54

I've finally got it to work, as follows (full Ansible playbook at the end).

I copy the original root partition to the new root partition, excluding some special mounts and (more significantly) the /boot directory contents, so I start from a clean slate:

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

Then install grub:

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

Generate grub config:

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

This doesn't include the vmlinuz or initrd images for later (assuming an empty boot partition), so copy those over:

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

Since the UUIDs are different, I need to update /mnt/root/boot/grub/grub.cfg and /mnt/root/etc/fstab, and replace every instance of the old UUID with the new one.

I also need to edit the ESP grub.cfg (in /mnt/esp/EFI/BOOT/grub.cfg) to look on hd0 instead of hd1.

I also removed reference to these /dev/sdb mounts from fstab, so all that is left is a line to mount the ESP, and one to mount /.

The whole Ansible playbook that does this for me is here:

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

    - name: Delete partitions
        device: "{{ device }}"
        number: "{{ item }}"
        state: absent
        - 1
        - 2

    - name: Create efi partition
        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
        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
        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
        path: /mnt/root
        src: "{{ device }}2"
        fstype: ext4
        state: mounted

    - name: Mount efi from the other device
        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
       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
        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
        path: /mnt/root/boot/grub/grub.cfg
        regexp: "{{ root_uuid.stdout }}"
        replace: "{{ new_root_uuid.stdout }}"

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

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

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

With these requirements:

  - community.general

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.