mkaczanowski / packer-builder-arm

Packer plugin to build ARM images
Apache License 2.0
315 stars 101 forks source link

Mount /etc/resolv.conf during extra setup #144

Open Lykos153 opened 3 years ago

Lykos153 commented 3 years ago

Before chrooting, packer-builder-arm mounts some additional directories which are necessary for the chroot environment to work. /etc/resolv.conf, however, is missing, resulting in network problems down the line, as can be seen in various tickets: #16 #68 #83 #113

Please, during extra setup, mount the host's resolv.conf

mkaczanowski commented 2 years ago

PRs are most welcome :)

I guess it should be as simple as:

mount --bind /etc/resolv.conf /.../etc/resolv.conf

^^ though I am not sure how portable this is, so if you could test it with systemd-resolved, resolvconf, plaintext resolv.conf and on MacOS X it would be great.

mkaczanowski commented 2 years ago

I expect it should work out of the box, but having someone to test it out would be great

mkaczanowski commented 2 years ago

For my own reference:

chrsoo commented 2 years ago

@mkaczanowski wrote:

I guess it should be as simple as:

mount --bind /etc/resolv.conf /.../etc/resolv.conf

Well... if that was the case could we not just use the additional_chroot_mounts in the packer file? I tried and it results in the following error:

==> arm: error creating mount directory: mkdir /tmp/561410291/etc/resolv.conf: file exists

... which I don't think is that surprising given that we are talking about a file or link and not a directory.

(UPDATE: the bind mount should work with two files the reason it is failing is because the chroot resolv.conf is a symlink pointing nowhere)

Also the BasicChroot Ubuntu article suggests copying the file.

I tried to implement a PR for this but my Go skills and knowledge of the codebase is not up to par it would seem as I can't make it work... I always get errors along the lines of

==> arm: error while creating destination: open /tmp/910554841/etc/resolv.conf: no such file or directory: '/tmp/910554841/etc/resolv.conf'

... which I don't quite understand as the upstream base images OS filesystem should be available in the temporary directory after setting up the chroot mounts...

I have tried patching the code base with the following snippet in several of the steps but always with the same result; perhaps you can spot the error?

src := "/etc/resolv.conf"
dst := filepath.Join(imageMountpoint, src)
source, err := os.Open(src)
if err != nil {
    ui.Error(fmt.Sprintf("error while opening source: %v: '%s'", err, src))
    return multistep.ActionHalt
}
defer source.Close()

// Should we backup the /etc/resolv.conf if it exist and restore it before creating the final image?
destination, err := os.Create(dst)
if err != nil {
    ui.Error(fmt.Sprintf("error while creating destination: %v: '%s'", err, dst))
    return multistep.ActionHalt
}
defer destination.Close()

_, err = io.Copy(destination, source)
if err == nil {
    ui.Message(fmt.Sprintf("copied file from '%s' to '%s'", src, dst))
} else {
    ui.Error(fmt.Sprintf("error while copying: %v: from '%s' to '%s'", err, src, dst))
    return multistep.ActionHalt
}

If you are able to provide a branch with a fix I will happily test it on my M1 Powerbook as the issue currently is blocking me from using the provisioner with ubuntu-20.04 images!

chrsoo commented 2 years ago

Maybe the problem is that /tmp/.../etc/resolv.conf on the mounted image is a symlink that points to nowhere? Then I guess deleting it before copying should resolve the issue...

michalfita commented 1 year ago

That symlink doesn't point to nowhere, but to a file that systemd manages on boot - my understanding is it's connected with Network Manager, so DNS addresses obtained from DHCP during roaming between networks work smoothly.

I'm doing this in my provisionings:

      "mkdir -p /run/systemd/resolve",
      "echo 'nameserver 1.1.1.1' > /run/systemd/resolve/stub-resolv.conf",