Skip to content

Alpine Linux support #1608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Alpine Linux support #1608

wants to merge 3 commits into from

Conversation

SamuelMarks
Copy link

@SamuelMarks SamuelMarks commented Mar 28, 2025

Description

Add Alpine Linux builds; basically a simple rewrite of the Fedora one

FYI: Testing on macOS (M3) with:

$ gem build bento.gemspec
$ gem install bento-*.gem
$ bento build --cpus 2 os_pkrvars/alpine/alpine-3.21-aarch64.pkrvars.hcl

Related Issue

Closes #1607

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (non-breaking change that does not add functionality or fix an issue)

Checklist:

  • I have read the CONTRIBUTING document.
  • I have run the pre-merge tests locally and they pass.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • If Gemfile.lock has changed, I have used --conservative to do it and included the full output in the Description above.
  • All new and existing tests passed.
  • All commits have been signed-off for the Developer Certificate of Origin.

@SamuelMarks SamuelMarks requested review from Stromweld and a team as code owners March 28, 2025 22:58
@SamuelMarks SamuelMarks requested a review from a team as a code owner April 1, 2025 20:10
…ferent virtual machines based on official alpine
Copy link

sonarqubecloud bot commented Apr 7, 2025

@rubisher
Copy link

Hello Samuel,
I was just looking for a support of Alpine in Bento to easily create my customized VBox images.
As much more interested in x86_64 virtual box images, I tried that first but the default boot_command is not understand by alpine boot process also I try to figure out how to start an unattended config and would like to suggest this first update:

diff --git a/os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl b/os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl
index 18a3b15..39ae540 100644
--- a/os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl
+++ b/os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl
@@ -6,4 +6,15 @@ iso_checksum            = "file:https://dl-cdn.alpinelinux.org/alpine/v3.21/rele
 parallels_guest_os_type = "otherlinux"
 vbox_guest_os_type      = "ArchLinux_64"
 vmware_guest_os_type    = "otherlinux-64"
-boot_command            = ["<wait><up>e<wait><down><down><end> inst.ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/fedora/ks.cfg inst.repo=https://download.fedoraproject.org/pub/fedora/linux/releases/41/Server/x86_64/os/ <F10><wait>"]
+boot_command            = ["<wait10>root<enter>ifconfig eth0 up<enter>",
+"setup-interfaces<enter><enter><enter><enter>",
+"setup-keymap<enter>us<enter>us<enter>",
+"setup-hostname<enter>alpinet1<enter>",
+"setup-timezone<enter>GMT<enter>",
+"setup-proxy<enter>none<enter>",
+"setup-ntp<enter>chrony<enter>",
+"setup-apkrepos<enter>c<enter><enter>",
+"setup-user -u vagrant<enter>",
+"setup-sshd<enter>openssh<enter>",
+"setup-disk<enter>sda<enter>lvm<enter>sys<enter>y<enter>",
+"reboot<enter>"]

This already help to setup vm but packer is not yet already able to connect to this vm via ssh :(
Any idea?

Thanks a lot for your nice job,
Rudy

@SamuelMarks
Copy link
Author

@rubisher Yeah I tried this one also https://wiki.alpinelinux.org/wiki/Packer_installation

The closest I've gotten to a working build is https://github.com/SamuelMarks/alpine-packer/tree/3.21

But would prefer the bento build working as it supports more VM systems (hypervisors, vendors) and architectures. The alpine IRC channel is the closest we'll get to official support on this FYI

In the meantime happy to collab

@Stromweld
Copy link
Collaborator

nice work so far guys thanks for the addition. let me know if you need any extra help. I've been pretty busy with work lately so I've been a bit spotty on further updates in here.

@rubisher
Copy link

@rubisher Yeah I tried this one also https://wiki.alpinelinux.org/wiki/Packer_installation

Ah, I see better: if I find well your arch boot_command, I was missing the answers file :) (Not easy to understand its contain :)

The closest I've gotten to a working build is https://github.com/SamuelMarks/alpine-packer/tree/3.21

But would prefer the bento build working as it supports more VM systems (hypervisors, vendors) and architectures. The alpine IRC channel is the closest we'll get to official support on this FYI

Same to me but quite sure the 2 proj used the same packer based also I really think it would possible to do some reverse engineering but I don't yet reach the Corey skill also I would need some more investigation,...

In the meantime happy to collab

Thanks again

@rubisher
Copy link

@rubisher Yeah I tried this one also https://wiki.alpinelinux.org/wiki/Packer_installation

Ah, I see better: if I find well your arch boot_command, I was missing the answers file :) (Not easy to understand its contain :)

https://git.alpinelinux.org/alpine-conf/tree/setup-user.in may be the place where I would learn how to create a vagrant user with its 'Insecure Keypair' https://github.com/hashicorp/vagrant/tree/master/keys, though???

The closest I've gotten to a working build is https://github.com/SamuelMarks/alpine-packer/tree/3.21
But would prefer the bento build working as it supports more VM systems (hypervisors, vendors) and architectures. The alpine IRC channel is the closest we'll get to official support on this FYI

Same to me but quite sure the 2 proj used the same packer based also I really think it would possible to do some reverse engineering but I don't yet reach the Corey skill also I would need some more investigation,...

In the meantime happy to collab

Thanks again

@rubisher
Copy link

rubisher commented Apr 19, 2025

Well imho some progress: from a simple VBox, I start it with the alpinelinux install dvd.
Run "setup-alpine -c answers" to create a default answers file which I can customize as follow:

KEYMAPOPTS="us us"
HOSTNAMEOPTS=alpine
DEVDOPTS=mdev
INTERFACESOPTS="auto lo
iface lo inet loopback
auto eth0
    iface eth0 inet dhcp
    hostname alpine
"
DNSOPTS="-d example.com 8.8.8.8"
TIMEZONEOPTS="UTC"
PROXYOPTS=none
APKREPOSOPTS="-1"
USEROPTS="-a -u -g audio,input,video,netdev vagrant"
USERSSHKEY="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
SSHDOPTS=openssh
NTPOPTS=busybox
DISKOPTS="-m sys /dev/sda"
LBUOPTS=none
APKCACHEOPTS=none

saved in 'packer_templates/http/alpine/answers' to use an './os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl':

os_name                 = "alpine"
os_version              = "3.21"
os_arch                 = "x86_64"
#iso_url                 = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-standard-3.21.3-x86_64.iso"
iso_url                 = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso"
#iso_checksum            = "file:https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-standard-3.21.3-x86_64.iso.sha256"
iso_checksum            = "file:https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso.sha256"
parallels_guest_os_type = "otherlinux"
vbox_guest_os_type      = "ArchLinux_64"
vmware_guest_os_type    = "otherlinux-64"

boot_command            = ["<wait10>root<enter>",
"setup-interfaces<enter><enter><enter><enter>",
"ifconfig eth0 up && udhcpc -i eth0<enter><wait5>",
"wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/alpine/answers<enter><wait>",
"setup-alpine -f answers<enter><wait5>",
"vagrant<enter><wait1>",
"vagrant<enter><wait1>",
"y<enter><wait10>",
"rc-service sshd stop<enter>",
"mount /dev/sda3 /mnt<enter>",
"echo 'PermitRootLogin yes' >> /mnt/etc/ssh/sshd_config<enter>",
"cat /mnt/etc/apk/repositories<enter><wait>",
"umount /mnt<enter>",
"reboot<enter>"]

for 'packer build -on-error=ask -only=virtualbox-iso.vm -var-file=./os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl ./packer_templates'.

Everything seems to be completed with success, after the final reboot, I can login as root with 'ssh -p xxxx root@localhost' (i.e. root passwd is correctly set) and as vagrant with his 'Insecure Keypair' (i.e /home/vagrant/.ssh/authorized_keys is also correctly setup), though.

BUT still stuck after the reboot ...

==> virtualbox-iso.vm: Using SSH communicator to connect: 127.0.0.1
==> virtualbox-iso.vm: Waiting for SSH to become available...
==> virtualbox-iso.vm: Timeout waiting for SSH.
==> virtualbox-iso.vm: Timeout waiting for SSH.
==> virtualbox-iso.vm: Step "StepConnect" failed
==> virtualbox-iso.vm: [c] Clean up and exit, [a] abort without cleanup, or [r] retry step (build may fail even if retry succeeds)? c

@Stromweld, any idea of what can I do to continue this matter ?
(the packer build -debug option don't learn me more why

==> virtualbox-iso.vm: Waiting for SSH to become available...

:()
PS: I tested the 2 releases "alpine-standard" and "alpine-virt" with the same result.

@rubisher
Copy link

rubisher commented Apr 21, 2025

You couldn't imagine how much I feeling stupid:
as I can login into to the vm, I would simply have to check /var/log/messages wivch would learn me that:

[...]
Apr 21 15:27:53 alpine auth.info sshd[2549]: Failed password for vagrant from 10.0.2.2 port 59852 ssh2
Apr 21 15:27:53 alpine auth.info sshd[2549]: Connection closed by authenticating user vagrant 10.0.2.2 port 59852 [preauth]
[...]

And unfortunately , I didn't find a clean way to setup the vagrant user password so I try this new os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl:

os_name                 = "alpine"
os_version              = "3.21"
os_arch                 = "x86_64"
iso_url                 = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso"
iso_checksum            = "file:https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso.sha256"
parallels_guest_os_type = "otherlinux"
vbox_guest_os_type      = "ArchLinux_64"
vmware_guest_os_type    = "otherlinux-64"
boot_command            = ["<wait20>root<enter>",
"setup-interfaces<enter><enter><enter><enter>",
"ifconfig eth0 up && udhcpc -i eth0<enter><wait5>",
"wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/alpine/answers<enter><wait>",
"setup-alpine -f answers<enter><wait5>",
"vagrant<enter><wait1>",
"vagrant<enter><wait1>",
"y<enter><wait10>",
"mount /dev/sda3 /mnt<enter>",
"echo 'PermitRootLogin yes' >> /mnt/etc/ssh/sshd_config<enter>",
"sed -i 's/^vagrant::/vagrant:\\$1\\$aRsPFEyR\\$9Qr\\/jfj7ig4PS039scMUi0:/' /mnt/etc/shadow<enter>",
"cat /mnt/etc/apk/repositories<enter><wait>",
"umount /mnt<enter>",
"reboot<enter>"]

(@SamuelMarks your other work https://github.com/SamuelMarks/alpine-packer/blob/3.21/virtualbox-iso.pkr.hcl choose to setup root as ssh user:

[...]
source "virtualbox-iso" "alpine" {
[...]
  ssh_username         = "root"
[...]

I don't yet find how is it possible to do in BENTO?)

That said, as alpine deprecated sudo in favour of doas in Alpine Linux since v3.15.0

[...]
==> virtualbox-iso.vm: Connected to SSH!
==> virtualbox-iso.vm: Uploading VirtualBox version info (7.0.22)
==> virtualbox-iso.vm: Uploading VirtualBox guest additions ISO...
==> virtualbox-iso.vm: Provisioning with shell script: ./packer_templates/scripts/alpine/networking_alpine.sh
==> virtualbox-iso.vm: sh: sudo: not found
==> virtualbox-iso.vm: Script exited with non-zero exit status: 127. Allowed exit codes are: [0]
==> virtualbox-iso.vm: Step "StepProvision" failed
==> virtualbox-iso.vm: [c] Clean up and exit, [a] abort without cleanup, or [r] retry step (build may fail even if retry succeeds)? 

I need to find out how BENTO could use doas in place of sudo ;)

Take care ;)

@rubisher
Copy link

Hello,
To continue investigation, I tried to use doas as follow:

└─$ diff -Nau ./packer_templates/pkr-builder.pkr.hcl.SM-ORIG ./packer_templates/pkr-builder.pkr.hcl
--- ./packer_templates/pkr-builder.pkr.hcl.SM-ORIG	2025-04-22 11:59:38.923636564 +0000
+++ ./packer_templates/pkr-builder.pkr.hcl	2025-04-22 12:57:03.406133703 +0000
@@ -194,7 +194,9 @@
       ]
     )
     execute_command = var.os_name == "freebsd" ? "echo 'vagrant' | {{.Vars}} su -m root -c 'sh -eux {{.Path}}'" : (
-      var.os_name == "solaris" ? "echo 'vagrant'|sudo -S bash {{.Path}}" : "echo 'vagrant' | {{ .Vars }} sudo -S -E sh -eux '{{ .Path }}'"
+      var.os_name == "alpine" ? "echo 'vagrant'| {{.Vars}} doas -u root 'sh -e {{.Path}}'" : (
+        var.os_name == "solaris" ? "echo 'vagrant'|sudo -S bash {{.Path}}" : "echo 'vagrant' | {{ .Vars }} sudo -S -E sh -eux '{{ .Path }}'"
+      )
     )
     expect_disconnect = true
     scripts           = local.scripts

Unfortunately, that failed because

==> virtualbox-iso.vm: Provisioning with shell script: ./packer_templates/scripts/alpine/networking_alpine.sh
==> virtualbox-iso.vm: doas: a tty is required
==> virtualbox-iso.vm: Script exited with non-zero exit status: 1. Allowed exit codes are: [0]
==> virtualbox-iso.vm: Step "StepProvision" failed

But I discover that the installation DVD comes with 'chroot' also it is possible to :

  1. setup more properly vagrant password
  2. install sudo
    during initial setup with this new ./os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl:
os_name                 = "alpine"
os_version              = "3.21"
os_arch                 = "x86_64"
iso_url                 = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso"
x86_64.iso.sha256"
iso_checksum            = "file:https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-virt-3.21.3-x86_64.iso.sha256"
parallels_guest_os_type = "otherlinux"
vbox_guest_os_type      = "ArchLinux_64"
vmware_guest_os_type    = "otherlinux-64"
ks.cfg inst.repo=https://download.fedoraproject.org/pub/fedora/linux/releases/41/Server/x86_64/os/ <F10><wait>"]
boot_command            = ["<wait20>root<enter>",
"setup-interfaces<enter><enter><enter><enter>",
"ifconfig eth0 up && udhcpc -i eth0<enter><wait5>",
"wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/alpine/answers<enter><wait>",
"setup-alpine -f answers<enter><wait5>",
"vagrant<enter><wait1>",
"vagrant<enter><wait1>",
"y<enter><wait10>",
"mount /dev/sda3 /mnt<enter>",
"echo 'PermitRootLogin yes' >> /mnt/etc/ssh/sshd_config<enter>",
"cat /mnt/etc/apk/repositories<enter><wait>",
"chroot /mnt<enter>",
"echo 'vagrant:vagrant' | chpasswd<enter>",
"sed -r 's!#(.*[0-9]\\/community)!\\1!g' -i /etc/apk/repositories<enter>",
"apk update<enter>",
"apk add sudo<enter>",
"echo 'vagrant ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vagrant<enter>",
"exit<enter>",
"umount /mnt<enter>",
"reboot<enter>"]

That works also may be can we simply revert ./packer_templates/pkr-builder.pkr.hcl to original config?

Now the last issues are the next scripts which don't look like busybox shell compatible:

==> virtualbox-iso.vm: Provisioning with shell script: ./packer_templates/scripts/alpine/networking_alpine.sh
==> virtualbox-iso.vm: + set -eux
==> virtualbox-iso.vm: /tmp/script_9738.sh: line 21: syntax error: unexpected end of file (expecting ";;")
==> virtualbox-iso.vm: Script exited with non-zero exit status: 2. Allowed exit codes are: [0]
==> virtualbox-iso.vm: Step "StepProvision" failed

@SamuelMarks: couldn't we reduce this scripts to ones you used in your 'alpine-packer' proj?

Hth,
Rudy

@Stromweld
Copy link
Collaborator

have you tried looking at setting it up with answer file like documented here https://docs.alpinelinux.org/user-handbook/0.1a/Installing/setup_alpine.html#_full_setup_alpine. The answer file can be added as a cdrom_file then boot command is to just run setup -f pointing to answer file. The answer file can live under http files etc... similar to kickstart files. even better if can use http_file option and -f can read file from http location

@rubisher
Copy link

rubisher commented Apr 22, 2025

have you tried looking at setting it up with answer file like documented here https://docs.alpinelinux.org/user-handbook/0.1a/Installing/setup_alpine.html#_full_setup_alpine. The answer file can be added as a cdrom_file then boot command is to just run setup -f pointing to answer file. The answer file can live under http files etc... similar to kickstart files. even better if can use http_file option and -f can read file from http location

Yes, what I was finaly suggesting put an "answers" file in 'packer_templates/http/alpine/answers':

KEYMAPOPTS="us us"
HOSTNAMEOPTS=alpine
DEVDOPTS=mdev
INTERFACESOPTS="auto lo
iface lo inet loopback
auto eth0
    iface eth0 inet dhcp
    hostname alpine
"
DNSOPTS="-d example.com 8.8.8.8"
TIMEZONEOPTS="UTC"
PROXYOPTS=none
APKREPOSOPTS="-1"
USEROPTS="-a -u -g audio,input,video,netdev vagrant"
USERSSHKEY="ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key"
SSHDOPTS=openssh
NTPOPTS=busybox
DISKOPTS="-m sys /dev/sda"
LBUOPTS=none
APKCACHEOPTS=none

And using a boot command like:

boot_command            = ["<wait20>root<enter>",
"setup-interfaces<enter><enter><enter><enter>",
"ifconfig eth0 up && udhcpc -i eth0<enter><wait5>",
"wget http://{{ .HTTPIP }}:{{ .HTTPPort }}/alpine/answers<enter><wait>",
"setup-alpine -f answers<enter><wait5>",
"vagrant<enter><wait1>",
"vagrant<enter><wait1>",
"y<enter><wait10>",
"mount /dev/sda3 /mnt<enter>",
"echo 'PermitRootLogin yes' >> /mnt/etc/ssh/sshd_config<enter>",
"cat /mnt/etc/apk/repositories<enter><wait>",
"chroot /mnt<enter>",
"echo 'vagrant:vagrant' | chpasswd<enter>",
"sed -r 's!#(.*[0-9]\\/community)!\\1!g' -i /etc/apk/repositories<enter>",
"apk update<enter>",
"apk add sudo<enter>",
"echo 'vagrant ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/vagrant<enter>",
"exit<enter>",
"umount /mnt<enter>",
"reboot<enter>"]

Such that we can use the "answers" file.

But the first issue is that I don't find a direct way to setup the password of "vagrant" :(
The option here is to use the chroot to set more or less cleanly this password.
Another option would also be to set the "ssh_username = root" in the os_pkrvars/alpine/alpine-3.21-x86_64.pkrvars.hcl. What is the best solution?

The second issue is that sudo was deprecated in favour of doas in Alpine Linux since v3.15.0 , unfortunately "doas" required a tty so I tried to re-use the chroot to install sudo. (is sudo will be ignored when we specify "ssh_username = root"?)

That was the most blocking points to me: the remaining ones looks to me quiet easy to fix ;)

That said, if there is an actual interest to add this distro in bento, I am not a developer also not very familiar on the way to help more the initial work of Samuel. (Do I have to fork his fork to suggest him some pull request??)

Thx in advance for further advises,
Rudy

@Stromweld
Copy link
Collaborator

if there is no clean way to set user/password I'd use root user and setup vagrant with scripts after the initial install. To make the boot command easier as well I'd use the answer file as a cdrom that can be mounted and then run setup command pointing to the answer file in it's mounted location. This simplifies things and removes dependency on network prior to install. since root is setup then that should also solve the doas configuration as it'd be done via a script after install and would then have a tty.

@Stromweld
Copy link
Collaborator

As for interest, you and samualmarks are the first to ask for it, but if you build it they will come. For the repo contributions that depends on how you want to collaborate. You may be able to clone his fork and just contribute directly to his branch if he didn't lock it down. however this can lead to issue where you over write each others stuff as you are testing and iterating. Ideally you'd fork his fork and commit to your own and then submit PR back to his fork for review and merging to his branch which then would come to this PR. This can be slower though especially when making many small changes to be more collaborative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Alpine Linux support
3 participants