I have been following the example on https://git.launchpad.net/cloud-init/commit?id=d8534561ba76db25b6fc0044eb1bfda63686e859 to make a system-user via cloud-init. I have been doing this on an Ubuntu Core Image that I am building. Unfortunately this seems to only work IF there is a stable connection (over ethernet). If there is no connection then, the “snap create-user” function will fail. Consequently the cloud-init will not run across a reboot.
I would like to see if any one had suggestions on how to retry to create this user using cloud-init or any other process. NOTE: I will be isolated from any USB/HDMI ports, so creating a system-user assertion via USB/keyboard will not be possible.
Here is my version of cloud-init that is in my gadget snapd:
Note that there is a native way to create system users in Ubuntu Core:
cloud-init, while it works for this too, is rather focused on automated cloud installs and adds some extra overhead. But if you have no access to the device at all it might be the best way (beyond simply dumping a user assertion into /writable/system-data/var/lib/snapd/seed/assertions during the flash process while you install the image to the system.
Also, adding the user creation to the gadget means indeed that all your installs have the same user.
Thanks ogra, you are correct it requires the extension *.assertion.
Also I found the solution to my issue. I simply created the assertion file, mount the *.img file, inject the assertion file, create a systemd-service that executes “create-user --sudoer --known”, then unmount the image.
When the ubuntu-core image boots, it will look for that assertion file and create the system-user.
Hi lopezem - I’m struggling with a similar problem, wanting to tailor the generated core image with a specific system user and network config.
First starting with the system user, I created user assertion and copying it to the root directory of a USB memory stick, creates this user account accordingly.
If I inject the user assertion to “…/system-data/var/lib/snapd/seed/assertions/” and change the extension to “.assertion” it will have no effect - meaning there is no user created and I’m not able to login :(.
Anything I missed?
In general, what is the best way to tailor an image to specific purposes? While searching on the internet, the most common solution I came across is using the cloud.conf file … is this the preferred method?
Hi @andreas, I believe you are correct in creating the system user assertion. What you need to do, (instead of placing the assertion file into the root directory of the USB) is after creating the ubuntu core image, you must mount the image.
I would highly recommend following the reference link I provided in the previous post in github. In a nutshell the script does the following:
Create a system-user assertion file.
Create a systemd service script to add the user during run time. I recommend sending logs to dmesg for debugging purposes in addition to what is provided in the repo
Create an ubuntu-core image file
Mount the generated image file to /tmp
Create the necessary directories for the assertion and systemd files/scripts
Copy the assertion file and systemd service scripts
Unmount the image file
Flash the image file to a USB/SD card
Boot the ubuntu core messages and monitor dmesg for debugging
P.S. I tried cloud-init functions. They kind of work but only for specific SSH keys, and it won’t really tie it to your ubuntu-one account.
Thanks @lopezem for the answer - I checked the reference on github and I didn’t like that it’s copying the systemd units from the core snap over, in order to add the “create-user” one time service (line 58-69).
It’s probably the best way to use a private snap package to do the initial setup of the system …