I figured out how to do what I needed, which was specifically:
- build a core image for the pi3
- that uses cloud-init
- to install a netplan file
- with eth0 set to a working static IP
- with a wifi access point declared with passphrase and auto-connecting
- with console-conf disabled
- and a system-user imported from a usb key on first boot
I made and use below some helper scripts, some of which are used: https://github.com/knitzsche/core-build-scripts
== Assume a model.json file:
{
"type": "model",
"system-user-authority": "*",
"authority-id": "MYSSOACOUNTID", <- NOT a real id
"brand-id": "MYSSOACCOUNTID", <- NOT real
"series": "16",
"model": "testmodel",
"architecture": "armhf",
"kernel": "pi2-kernel",
"gadget": "pi3",
"timestamp": "2017-07-11T15:55:59+00:00"
}
== Make the model assertion using “model” key (see -h)
$ ./make-model-assertion.sh model-pi3.json model > model.assertion
You need a passphrase to unlock the secret key for
user: "model"
4096-bit RSA key, ID C215EA0F, created 2017-01-01
== Make the image and put it in img-test:
$ sudo ./make-img.sh model.assertion stable img-test
Fetching core
Fetching pi2-kernel
Fetching pi3
built: img-test, with model: model.assertion, from channel: stable
== Enable the image for cloud-init
$ sudo ./enable-cloud-init.sh img-test/pi3.img
loop_path: /dev/mapper/loop17p2
Removing cloud-init.disabled file
done: img-test/pi3.img
== Disable console-conf
$ sudo ./disable-console-conf.sh img-test/pi3.img
loop_path: /dev/mapper/loop17p2
done: img-test/pi3.img
== Mount the writable partition of the image
$ sudo ./mount-do-nothing.sh img-test/pi3.img
loop_path: /dev/mapper/loop17p2
The image is now mounted in mnt/
Press any key to unmount and complete
== In another terminal in same dir, copy a netplan file like this to the correct place in the mounted partition
The netplan file
$ cat mynetplan.yaml
network:
version: 2
ethernets:
eth0:
addresses:
- 10.0.0.244/24
gateway4:
10.0.0.1
wifis:
wlan0:
dhcp4:
true
access-points:
"myap":
password:
"mypassword"
Make the dir in the mounted partition, and copy the netplan file in
$ sudo mkdir mnt/system-data/etc/netplan
$ sudo cp mynetplan.yaml mnt/system-data/etc/netplan/01-custom.yaml
=== In previous terminal press Enter to unmount
$ sudo ./mount-do-nothing.sh img-test/pi3.img
loop_path: /dev/mapper/loop17p2
The image is now mounted in mnt/
Press any key to unmount and complete
[ENTER]
$
== dd the image to SD card inserted and mounted to /dev/sdb
WARNING: This script assumes SD is on sdb. It will erase all data on sdb. So you might want to do it manually!
$ sudo ./dd-to-sdb.sh img-test/pi3.img
19+1 records in
19+1 records out
634260480 bytes (634 MB, 605 MiB) copied, 7.7398 s, 81.9 MB/s
$
== Unmount the two partitions on sdb
$ sudo umount /dev/sdb1
$ sudo umount /dev/sdb2
== Remove the SD card
== Make a system-user assertion
$ snap install make-system-user
See make-system-user.run -h to see how to fill in fields
Run it perhaps like this, given the above model.json and the existence of a snapcraft key named “kykey”
$ make-system-user.run -b MYSSOACCOUNTID -m testmodel -u ubuntu -p ubuntu -k mykey
You need a passphrase to unlock the secret key for
user: "mykey"
4096-bit RSA key, ID C375E301, created 2016-01-01
Done. You may copy auto-import.assert to a USB stick and insert it into an unmanaged Core system, after which you can log in using the username and password you provided.
And copy the generated auto-import.assert file to the root dir of your USB key.
== Insert SD, USB and boot
Should work as expected (although nothing yet creates the /etc/cloud/cloud-init.disabled command after first boot, so cloud init would run on every boot, a solvable problem, maybe with a custom systemd unit)