Create FreeBSD Current OpenStack image on OVH Public Cloud

Introduction
For my project, I want to use FreeBSD on the OVH’s Public Cloud.
Behind this service, it’s OpenStack who run your instances.
Actually, OVH just offer FreeBSD-11.0. Too old, and I prefer CURRENT branch and recompile it from source every week.
Another problem is bscloud-init doesn’t run on FreeBSD-12 and older because it use an too old version of Python.
Well, before start, I list my needs:
- FreeBSD-Current branch
- ZFS
- growfs during the first boot
- configure hostname during the boot
- push key for ssh
- can execute post-install script
- generate new hostid at the first boot
- already configured public net interface
First, I wrote a lightweight shell script to be my cloud-init during instance boot.
You’ll find it into this github repo:
GitHub - fredericalix/cloud-init: OpenStack FreeBSD cloud-init in bash script
After some tests, I toke the decision to use HashiCorp Packer to compile the kernel from source and update packages every week.
Before that, I need a minimum things. My first image must boot and configure ip address by DHCP and include the public ssh key used by my packer template.
I’ll create it on my workstation in qemu, and upload it with OpenStack CLI.
To finish, I’ll execute the Packer template who install cloud-init, pull FreeBSD-CURRENT source, compile it, update pkg and create the final OpenStack image.
Install FreeBSD-CURRENT in a QEMU VM
Prerequisites
-
In this case, I’ll build the first image on my Ubuntu workstation with virt-manager
(sudo apt install -y virt-manager
) -
You’ll need openstack client. On ubuntu, install it with
sudo apt install -y python3-openstackclient
-
Install packer on your workstation → Download Packer - Packer by HashiCorp
-
Download FreeBSD-CURRENT iso at Index of /pub/FreeBSD/snapshots/ISO-IMAGES/13.0/
-
Create a ssh key for Packer :
ssh-keygen -t rsa -b 4096 -f \~/.ssh/id_rsa_packer
-
Download openrc concerning your Public Cloud project.
Go to https://www.ovh.com/manager/public-cloud/index.htm
Project Management → Users & Roles → Create User
Save your password into your password manager ;)
Project Management → Users & Roles → … → Download OpenStack’s RC file\
Select your region and user OpenRC v3 config file and click Download
Create VM on the workstation
I’ll don’t explain how to use virt-manager. You’ll find a lot of documentation into your favorite search engine.
The most important is:
- 4 GB of RAM
- 1 vcpu is enough to install
- use virtio for your virtual hard drive
- use virtio for your virtual network card
FreeBSD installation steps
Create a freebsd
user. It will be the only user of your instance when you’ll create it.
Later we’ll give it admin privileges with sudo
.
Configure FreeBSD before push it on OpenStack
On the console connect with root user to show the ip address
Now you can connect to it by ssh
ssh freebsd@192.168.122.250
But before we need to install and configure sudo. Stay connected in your QEMU console and type:
pkg update
pkg install -y sudo
visudo
Insert this line into the visudo editor:
freebsd ALL=(ALL) NOPASSWD: ALL
Now you can connect to your vm by ssh. It will be more easy to edit your files.
Put packer ssh key on freebsd account
mkdir .ssh
chmod go-rwx .ssh
cd .ssh
vi authorized_keys
Paste your \~/.ssh/id_rsa_packer.pub
in authorized_keys
Install packages
sudo pkg install -y bash wget curl
dhcp client configuration for OVH network route
sudo vi /etc/dhclient-exit-hooks
# This script fixes injection of the default route on OVH /cloud.
# See dhclient-script(8) for more details.
# Force-add a static route to our gateway (otherwise unreachable)
# and re-declare it as the default route (as previous declaration failed)
case "${reason}" in
"BOUND"|"RENEW"|"REBIND"|"REBOOT")
route add "${new_routers}" -iface "${interface}"
route add default "${new_routers}"
;;
*)
;;
esac
Few OpenStack-specific changes
sudo -s
echo 'console="comconsole,vidconsole"' >> /boot/loader.conf
echo 'autoboot_delay="1"' >> /boot/loader.conf
Shrink image
Halt your vm
halt -p
Now it it time to shrink your image to be more smaller.
Locate your vm data file. In my case, it is /var/lib/libvirt/images/
root@ubuntu-desktop:/var/lib/libvirt/images# ls -lh
total 11G
-rw------- 1 root root 11G août 15 21:11 freebsd-current.qcow2
To shrink it:
qemu-img convert -O qcow2 freebsd-current.qcow2 freebsd-current_small.qcow2
ls -lh
root@ubuntu-desktop:/var/lib/libvirt/images# ls -lh
total 12G
-rw------- 1 root root 11G août 15 21:11 freebsd-current.qcow2
-rw-r--r-- 1 root root 1,2G août 15 21:18 freebsd-current_small.qcow2
Upload your FreeBSD openstack image to OVH Public Cloud
It’s time to upload our image.
First, you need to load your openrc.sh profile (read prerequisites section) and display actual images to see if your openstack client is correctly configured
. ~/openrc.sh
openstack image list
Now upload the image:
openstack image create --private --disk-format qcow2 --container-format bare --property image_original_user=freebsd --property hw_disk_bus='scsi' --property hw_scsi_model=virtio-scsi --file freebsd-current_small.qcow2 freebsd-current_phase-1
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| checksum | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| container_format | bare |
| created_at | 2019-08-15T19:33:38Z |
| disk_format | qcow2 |
| file | /v2/images/XXXXXXXXXXXXXXXX/file |
| id | XXXXXXXXXXXXXXXXXXXXXXXXXX |
| min_disk | 0 |
| min_ram | 0 |
| name | freebsd-current_phase-1 |
| owner | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| properties | direct_url='swift+config://ref1/glance/XXXXXXXXb3-fb65d7c74b9f', hw_scsi_model='virtio-scsi', locations='[{'url': 'swift+config://ref1/glance/XXXXXXXXXXXXXXb3-fb65d7c74b9f', 'metadata': {}}]' |
| protected | False |
| schema | /v2/schemas/image |
| size | 1196621824 |
| status | active |
| tags | |
| updated_at | 2019-08-15T22:19:29Z |
| virtual_size | None |
| visibility | private |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Verify image
openstack image list --private
+--------------------------------------+-------------------------+--------+
| ID | Name | Status |
+--------------------------------------+-------------------------+--------+
| f5d9db47-ddc1-49c3-a7b3-fb65d7c74b9f | freebsd-current_phase-1 | active |
+--------------------------------------+-------------------------+--------+
Important:
Don’t use this image for your production or anything else. It is just a draft and we’ll use it in the next section to build the final image, with cloud-init and another things.
Using HashiCorp Packer to build the final FreeBSD-CURRENT OpenStack image
In this step, we’ll use Packer to build our final image.
The template will:
- copy
cloud-init.sh
script to/etc/rc.local
- resize disk partition and the zpool
- download FreeBSD code source on github
- Build world and kernel
- Install kernel and world
- Upgrade packages
- Set no password to root and freebsd users
First, add your packer ssh key we created earlier
ssh-add ~/.ssh/id_rsa_packer
Display and note your ID Ext-Net network. You’ll need it to configure Packer.
openstack network list --name Ext-Net -c ID
+--------------------------------------+
| ID |
+--------------------------------------+
| xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
+--------------------------------------+
Clone my Packer template
git clone https://github.com/fredericalix/packer-freebsd.git
cd packer-freebsd
mkdir /var/tmp/packer
Edit openstack_ovh.json
and replace the networks section with your network uuid
{
"builders": [
{
"flavor": "b2-7",
"image_name": "freebsd-current_final",
"image_visibility": "private",
"insecure": "false",
"networks": [
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
],
...
Now run Packer and take a very long coffee.
The buildworld operation take ~ 4 hours.
packer build openstack_ovh.json
When it will be over, verify image availability
openstack image list --private
+--------------------------------------+-------------------------+--------+
| ID | Name | Status |
+--------------------------------------+-------------------------+--------+
| 70556385-12ea-43fc-967b-4b3afa8326bf | freebsd-current_final | active |
| f5d9db47-ddc1-49c3-a7b3-fb65d7c74b9f | freebsd-current_phase-1 | active |
+--------------------------------------+-------------------------+--------+
Now you can use it ;)
Have fun !