canonical / multipass

Multipass orchestrates virtual Ubuntu instances
https://multipass.run
GNU General Public License v3.0
7.89k stars 652 forks source link

Error loading cloud-init config: bad file - multipass and cloud-init #3693

Closed tersucorp closed 1 month ago

tersucorp commented 1 month ago

Describe the bug I get the error below when trying to create vms with multipass and cloud init.

error loading cloud-init config: bad file
error loading cloud-init config: bad file
error loading cloud-init config: bad file
error loading cloud-init config: bad file

To Reproduce

  1. install multipass 1.14.0

  2. install cloud init 24.2-0ubuntu1~24.04.2

  3. create a cloud-init config file in config/debian-cloud-init.yaml:

    #cloud-config
    package_update: true
    packages:
    - debootstrap
    users:
    - name: root
    lock_passwd: false
    passwd: tersu
    ssh_pwauth: true
    disable_root: false
    runcmd:
    - debootstrap --arch=arm64 bookworm /mnt http://deb.debian.org/debian/
    - mount --bind /dev /mnt/dev
    - mount --bind /proc /mnt/proc
    - mount --bind /sys /mnt/sys
    - |
      chroot /mnt /bin/bash -c "apt-get update && \
      apt-get install -y linux-image-arm64 systemd-sysv"
    - chroot /mnt /bin/bash -c "apt-get install -y grub-efi"
    - |
      chroot /mnt /bin/bash -c "grub-install --target=arm64-efi \
      --efi-directory=/boot/efi --bootloader-debian --recheck"
    - chroot /mnt /bin/bash -c "update-grub"
    - |
      chroot /mnt /bin/bash -c "echo 'deb http://deb.debian.org/debian/ \
      bookworm main' > /etc/apt/sources.list"
    - chroot /mnt /bin/bash -c "echo 'root:password' | chpasswd"
    - |
      chroot /mnt /bin/bash -c "sed -i 's/^#PermitRootLogin.*/\
      PermitRootLogin yes/' /etc/ssh/sshd_config"
    - chroot /mnt /bin/bash -c "systemctl enable ssh"
    - umount /mnt/dev
    - umount /mnt/proc
    - umount /mnt/sys
    - echo "Debian installation completed!"
  4. Create a bash script to create vms using multipass and cloud-init

    
    #!/bin/bash

Launch VMs with multipass

multipass launch --name jumpbox --cpus 1 --memory 512M --disk 5G --cloud-init ./config/debian-cloud-init.yaml --verbose multipass launch --name master --cpus 1 --memory 2G --disk 10G --cloud-init ./config/debian-cloud-init.yaml --verbose multipass launch --name worker1 --cpus 1 --memory 2G --disk 10G --cloud-init ./config/debian-cloud-init.yaml --verbose multipass launch --name workder2 --cpus 1 --memory 2G --disk 10G --cloud-init ./config/debian-cloud-init.yaml --verbose


5. Run the bash script

**Expected behavior**
It should create the multipass VMs with the specified config

**Logs**
[multipass log file.log](https://github.com/user-attachments/files/17115735/multipass.log.file.log)

**Additional info**
 - OS: OS: Ubuntu 24.04.1 LTS x86_64
 - multipass version `1.14.0`
- cloud init version `24.2-0ubuntu1~24.04.2`
- `multipass get local.driver`: qemu

**Additional context**

config is valid

cloud-init schema -c config/debian-cloud-init.yaml 13:31:44 Valid schema config/debian-cloud-init.yaml

tersucorp commented 1 month ago

@townsend2010 - please what do you think of this?

tersucorp commented 1 month ago

I wrote a short script to validate the yaml using yaml-cpp and the result is that the yaml config is valid.

#include <iostream>
#include <yaml-cpp/yaml.h>

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <yaml_file>" << std::endl;
        return 1;
    }

    try {
        YAML::Node config = YAML::LoadFile(argv[1]);
        std::cout << "YAML is valid." << std::endl;
    } catch (const YAML::ParserException& e) {
        std::cerr << "YAML validation error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

./validate_yaml config.yaml YAML is valid.

georgeliao commented 1 month ago

Hi @tersucorp

Sorry that you have encountered this problem. I gave a quick try on the cloud-init yaml you have made, I was able to launch vms with the exact commands and scripts successfully on snap based multipass, version 1.14, on ubuntu 24.10. Not sure why it failed in your case. One suspicion is that there might be a small format difference between the yaml script you pasted and the one in your file, and that causes yaml parsing fails.

tersucorp commented 1 month ago

Thank you for responding @georgeliao I copied the exact file I have also tried validating the file locally as you can see in all the details I provided.

This is the link to the repository with the code.

https://github.com/davidshare/Kubernetes-tasks/tree/master/multipass-k8s-cluster

tersucorp commented 1 month ago

To provide more clarity, this is a link t a video recording.

https://streamable.com/5lsocy

georgeliao commented 1 month ago

Thank you for responding @georgeliao I copied the exact file I have also tried validating the file locally as you can see in all the details I provided.

This is the link to the repository with the code.

https://github.com/davidshare/Kubernetes-tasks/tree/master/multipass-k8s-cluster

I git cloned the repo and ran sh create-vms.sh, everything worked fine. Not sure what is making the difference.

tersucorp commented 1 month ago

Are there any other configurations I need to be aware of? I have uploaded my multipass logs below.

multipass-log.log

tersucorp commented 1 month ago

@georgeliao - please where you able to take a look at the logs? I would really appreciate your help. I am still stuck on this, and I really want to understand this tool

tersucorp commented 1 month ago

finally found what I think the issue is. Snap is denying multipass access to my mounted drive:

apparmor="DENIED" operation="open" class="file" profile="snap.multipass.multipass"

georgeliao commented 1 month ago

@tersucorp Sorry for the late reply, there were many other issues required my attention.

finally found what I think the issue is. Snap is denying multipass access to my mounted drive: apparmor="DENIED" operation="open" class="file" profile="snap.multipass.multipass"

The might be the cause, can you try it on a native drive so the cause of the issue can be confirmed? In order to fix that, a few things you can ,

  1. Reinstall multipass via sudo snap install multipass --classic, the --classic option puts snap in classic mode and disables security confinement. This might relax the access requirement.
  2. Use chmod to grant your mounted drive the appropriate permissions.
tersucorp commented 1 month ago

Further investigation showed the issue was caused by apparmor blocking multi pass on snap. Unfortunately, trying to fix that has further worsened since snap no longer works.

Apparmor keeps blocking any snap related commands because of snap-confine permissions. I'm still digging.

@tersucorp Sorry for the late reply, there were many other required my attention.

finally found what I think the issue is. Snap is denying multipass access to my mounted drive: apparmor="DENIED" operation="open" class="file" profile="snap.multipass.multipass"

The might be the cause, can you try it on a native drive?

georgeliao commented 1 month ago

@tersucorp Two things you can try,

  1. Reinstall multipass via sudo snap install multipass --classic, the --classic option puts snap in classic mode and disables security confinement. This might relax the access requirement.
  2. Use chmod to grant your mounted drive the appropriate permissions.
tersucorp commented 1 month ago

I've done all that, including reinstalling snap.

The challenge is now with snapd and apparmor.

@tersucorp Two things you can try,

  1. Reinstall multipass via sudo snap install multipass --classic, the --classic option puts snap in classic mode and disables security confinement. This might relax the access requirement.
  2. Use chmod to grant your mounted drive the appropriate permissions.
ricab commented 1 month ago

Hi @tersucorp, the Multipass snap is a strictly confined snap. This means that it is limited on what it can do or access on your host. Adding --classic when installing doesn't help, it is just ignored.

You should be able to run this by coping your file to your home folder. Or, if on an external drive, snap connect multipass:removable-media may help.

You can also bypass the issue entirely by using your shell to redirect the cloud-init contents. Something like

multipass launch ... --cloud-init - < /path/to/your/cloud-init.yaml
tersucorp commented 1 month ago

Hi @tersucorp, the Multipass snap is a strictly confined snap. This means that it is limited on what it can do or access on your host. Adding --classic when installing doesn't help, it is just ignored.

You should be able to run this by coping your file to your home folder. Or, if on an external drive, snap connect multipass:removable-media may help.

You can also bypass the issue entirely by using your shell to redirect the cloud-init contents. Something like

multipass launch ... --cloud-init - < /path/to/your/cloud-init.yaml

Thank you

I had connected the removable media. Then while looking at the logs I realised that it was been blocked by apparmor. On trying to fix the apparmor profile, I think I kind of messed things up. Snap is totally blocked by apparmor now because of snap-confine.

I've been trying to resolve that.

The details are here:

https://askubuntu.com/questions/1528440/snap-confine-has-elevated-permissions-and-is-not-confined-but-should-be

Hopefully, after fixing it, multipass should work.

ricab commented 1 month ago

OK, that's beyond Multipass, I am afraid.

I am going to repurpose this as an enhancement to improve the error message.