Lxc profile show does not work for multi-line profiles

In this test, a single-line profile is compared agains a multi-line profile. The other profiles are excluded for brevity.

sudo lxc profile list
...
+-------------------------------------------------------------------------------------------+--------------------------+---------+
| proxyPortTCP-20000-20999                                                                  | Custom VM Broker profile | 1       |
+-------------------------------------------------------------------------------------------+--------------------------+---------+
| raw.lxc-lxc.apparmor.profile=unconfined                                                   | Custom profile           | 5       |
| lxc.cap.drop=                                                                             |                          |         |
| lxc.cgroup.devices.allow=a                                                                |                          |         |
| lxc.mount.auto=proc:rw sys:rw                                                             |                          |         |
+-------------------------------------------------------------------------------------------+--------------------------+---------+
...

Observe profiles exist

sudo curl -s --unix-socket /var/snap/lxd/common/lxd/unix.socket -X GET a/1.0/profiles | jq .
...
    "/1.0/profiles/proxyPortTCP-20000-20999?project=default",
    "/1.0/profiles/raw.lxc-lxc.apparmor.profile%20=%20unconfined%0Alxc.cgroup.devices.allow%20=%20a%0Alxc.mount.auto%20=%20proc:rw%20sys:ro%0Alxc.cap.drop%20=?project=default",
...

Examine profiles. Observe single-line profile

sudo lxc profile show "proxyPortTCP-20000-20999"
name: proxyPortTCP-20000-20999
description: Custom profile
config: {}
devices:
  port80:
    connect: tcp:127.0.0.1:80
    listen: tcp:0.0.0.0:80
    proxy_protocol: "true"
    type: proxy
  port443:
    connect: tcp:127.0.0.1:443
    listen: tcp:0.0.0.0:443
    proxy_protocol: "true"
    type: proxy
  port20000-20999:
    connect: tcp:127.0.0.1:20000-20999
    listen: tcp:0.0.0.0:20000-20999
    type: proxy
used_by:
- /1.0/instances/node7

Observe failure to show multi-line profile

sudo lxc profile show "raw.lxc-lxc.apparmor.profile%20=%20unconfined%0Alxc.cgroup.devices.allow%20=%20a%0Alxc.mount.auto%20=%20proc:rw%20sys:ro%0Alxc.cap.drop%20="
Error: The remote "raw.lxc-lxc.apparmor.profile%20=%20unconfined%0Alxc.cgroup.devices.allow%20=%20a%0Alxc.mount.auto%20=%20proc" doesn't exist

Is there any way to run lxc profile show on multi-line profiles?

Hi!

This support forum is for Incus, which is a continuation of LXD.
Here is how to migrate from LXD to Incus or my post.

What you get there from accessing the Unix socket, is messed up profile names. There shouldn’t be any reference to raw.lxc-lxc.apparmor.profile... or ?project=default.

The output seems fine here, you have one profile named proxyPortTCP-20000-20999 and one profile that’s named:

raw.lxc-lxc.apparmor.profile=unconfined
lxc.cap.drop=
lxc.cgroup.devices.allow=a
lxc.mount.auto=proc:rw sys:rw

Now that’s one awful profile name and it looks like someone just put what was meant to go as profile config into the profile name, but the API and CLI seems to show it correctly :slight_smile:

I expect you don’t use HTML escaping when using the CLI, try replacing %20 with space and %0A with newline.

It’s going to be horrendous to get right though. Also, the error saying “The remote … doesn’t exist” suggests that the colon within the name is being interpreted as a separator between remote and name, so you might need to prefix it all with local:. Maybe like this:

sudo lxc profile show "local:raw.lxc-lxc.apparmor.profile = unconfined
lxc.cgroup.devices.allow = a
lxc.mount.auto = proc:rw sys:ro
lxc.cap.drop ="

lxd/incus profile list --format=json may make it clearer exactly what you need to give.

I suspect, though, that profiles could do with better validation in their names! :slight_smile: (Especially given that a container name can’t even contain a dot)

1 Like

This is the solution that worked immediately for me.

sudo lxc profile show "local:raw.lxc-lxc.apparmor.profile=unconfined
lxc.cap.drop= 
lxc.cgroup.devices.allow=a
lxc.mount.auto=proc:rw sys:rw"
name: "raw.lxc-lxc.apparmor.profile=unconfined\nlxc.cap.drop= \nlxc.cgroup.devices.allow=a\nlxc.mount.auto=proc:rw
  sys:rw"
description: Custom profile
config:
  raw.lxc: "lxc.apparmor.profile=unconfined\nlxc.cap.drop= \nlxc.cgroup.devices.allow=a\nlxc.mount.auto=proc:rw
    sys:rw"
devices: {}
used_by:
- /1.0/instances/test-instance

For containers it’s because we’re respecting some of the RFCs around hostnames, for everything else the main criteria is that we don’t allow slashes as that interferes with URLs, anything else is usually fine on our end (though clearly can lead to some confusion as shown here :)).

Using an FQDN in /etc/hostname works fine though. Having to give a container a fake name like foo-example-com and then patch up /etc/hostname and /etc/hosts afterwards, and/or set a custom property like user.fqdn with the real, globally-unique name, is tedious. However, I’m not going to argue that point here: it was argued a long time ago, and lost.

I can accept that it’s better to be overly-restrictive than overly-permissive with hostnames, and by the same logic I think it would be reasonable to restrict profile names, network names, image names etc. Maybe not quite as restrictive as hostnames, but in particular there are issues if you allow a colon. Leading/trailing spaces and embedded newlines clearly cause confusion too.