I wanted to be able to run lxc exec on VMs without rebooting for automation purposes, I achieved this with the following profile in case anyone need this:
config:
user.user-data: | #cloud-config
ssh_pwauth: yes
apt_mirror: Index of /ubuntu
users:
- name: ubuntu
passwd: “$6$SaltSalt$/oLlBqBTXG/VR/9XsOXUUcMqwTBd5gzRCcs7Xtbr3cplQCh3Kkq33nyYml9MAF9C3zjfpAvySydIMD9q4KciX/”
lock_passwd: false
groups: lxd
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
runcmd:
- mount -t 9p config /mnt/
- cd /mnt/ && ./install.sh
- cd / && umount /mnt
- systemctl start lxd-agent-9p lxd-agent
description: VM specific configuration
devices:
config:
source: cloud-init:config
type: disk
Unless you’re using a cloud image, the image is going to have a 4GB / as you have above.
The 96GB is for the agent config drive and shows disk information from the host rather than your VM.
We allocate a 10GB large volume by default, but unless you’re using the cloud images, you need to manually handle any resizing yourself as LXD doesn’t want to go resize partitions on you.
I’ve followed your instructions to the letter but keep getting login incorrect. I generated my password using the command mkpasswd -m sha-512 and plonked into my profile for virtual-machines which looks like this:
When you create a container or a VM, you need to specify the storage device (i.e. the root:).
You could very well copy the root: entry from the default profile to all other profiles, like the VM profile. Or, when you create a container or VM, you can always specify the default profile, and on top of that, add a vm profile that has additional configuration. This is about stacking two separate profiles together. In my blog post I suggest the latter.
I also get the
[ 9.294197] cloud-init[719]: 2020-03-21 19:32:12,041 - util.py[WARNING]: Failed at merging in cloud config part from part-001
but can get a shell into the container. When I say I can get a shell, I mean either with lxc console or ssh. lxc exec requires to setup the LXD Agent first.
Here are the details of the warning/error.
2020-03-21 19:32:12,040 - __init__.py[DEBUG]: Calling handler CloudConfigPartHandler: [['text/cloud-config', 'text/cloud-config-jsonp']] (text/cloud-config, part-001, 3) with frequency once-per-instance
2020-03-21 19:32:12,041 - util.py[DEBUG]: Attempting to load yaml from string of length 13 with allowed root types (<class 'dict'>,)
2020-03-21 19:32:12,041 - util.py[DEBUG]: loaded blob returned None, returning default.
2020-03-21 19:32:12,041 - util.py[WARNING]: Failed at merging in cloud config part from part-001
2020-03-21 19:32:12,047 - util.py[DEBUG]: Failed at merging in cloud config part from part-001
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/cloudinit/handlers/cloud_config.py", line 140, in handle_part
self._merge_part(payload, headers)
File "/usr/lib/python3/dist-packages/cloudinit/handlers/cloud_config.py", line 116, in _merge_part
(payload_yaml, my_mergers) = self._extract_mergers(payload, headers)
File "/usr/lib/python3/dist-packages/cloudinit/handlers/cloud_config.py", line 95, in _extract_mergers
mergers_yaml = mergers.dict_extract_mergers(payload_yaml)
File "/usr/lib/python3/dist-packages/cloudinit/mergers/__init__.py", line 83, in dict_extract_mergers
raw_mergers = config.pop('merge_how', None)
AttributeError: 'NoneType' object has no attribute 'pop'
2020-03-21 19:32:12,050 - __init__.py[DEBUG]: Calling handler CloudConfigPartHandler: [['text/cloud-config', 'text/cloud-config-jsonp']] (__end__, None, 3) with frequency once-per-instance
I’ve been throwing everything (including the proverbial kitchen sink) at this problem and I haven’t made any progress. So, the obvious conclusion is that I have very little understanding of what I’m doing when I’m modifying this profile.
So, to that effect, can someone point me to the documentation where it documents what the lines below are really doing (as in line by line) and what files (if any) are being created by these actions in the container. Once all this is understood, then we all (really I) stand a better chance of getting stuff working instead of fighting the system.
What exactly am I changing in the container when I add this profile to it:
ssh_pwauth authorizes ssh password authentication.
The rest creates an ubuntu user, who’s part of the lxd group, has password authentication enabled, full sudo rights and the password you specified (hashed).
Note that cloud-init runs exactly once, on first boot of an instance.
So every time you want to test a change to your cloud-init config, you must create a new instance with that profile applied at launch time.
@stgraber is there a website or place in official documentation which holds howtos like this one?
If there isn’t, I would suggest creating the howto section of the official documentation and moving a lot of content from your personal website (thank you for examples there) and examples such as this one from your post, there. So it’s all in one place, what do you think?
thanks! please do.
I currently use multipass for vms, but having lxd on my machine for everything else, I’d also like to use it for vms.
It would be great if vm support in lxd is improved so launching vms is as simple as with multipass.