How to tell the lxc client utility to output in machine-readable format?

I’m trying to convince the lxc binary (version 3.4) to output data in a fashion that can be easily worked with from a shell script. Alas, I notice that the really useful flag --format csv, for example, is not universally usable.

For example it’s possible to do lxc image list --format csv -c f, but not many commands accept a similar flag. For example lxc --format csv profile list results in Error: unknown flag: --format, while lxc profile list shows a “table” using ASCII art.

Similarly lxc profile device list <profilename> does not accept the --format flag either. Not too bad, because it seems to print a plain list of device names, one per line.

However, in the last case I am unsure if I can rely on that or if the output might arbitrarily be changed to the fancier “table” appearance in newer versions.

So in addition to the question from the subject line on how to get lxc to output easily parseable data, I’d like to ask what the policy is regarding the “stability” of the output format, as that’s effectively an interface into the software (and lends itself to use inside scripts).

Thanks and best regards.

Indeed, the --fornat option is not uniformally available in all commands. In cases that it was missing, I have seen feature requests on this on the Issues at https://GitHub.com/lxc/lxd

Therefore, you can file a feature request for this.

In a lot of cases, doing the actual API call you want is the easiest, for example:

  • lxc query /1.0/containers/blah/state

That will always get you JSON which you can then filter and map using jq.

I think we want to make it so that all the list commands behave the same. I’m not sure that we want to add --format to the other commands though as commands like info don’t actually show you a single API object which makes it hard as to what JSON struct we should map that to.

I think having the list commands support formatting combined with lxc query should cover most needs.

2 Likes

Hey Stéphane,

what I am most interested in, though, is to get rid of the ASCII table part. I mean I’ve been filtering output from commands all the time. But when the output gets “prettified” that makes the job hard. After all that’s the Unix philosophy to chain commands like that. But since you recommend using JSON instead, I guess I’ll have to read up about that.

Is there something that could tell me which lxc command maps to which API query (I don’t know, some switch of lxc which lets me see those queries behind the scenes)?

Thanks!

I think you should expect that the tables are bound to change at some point in the future.

To use the API, have a look at

Here is the section on profiles. It is somewhat straightforward to associate which lxc subcommand corresponds to which API endpoint.

To get a list of the available profiles, consult the above URL and run the following:

$ curl -s -k --cert ~/.config/lxc/client.crt --key ~/.config/lxc/client.key https://127.0.0.1:8443/1.0/profiles | jq .metadata
[
  "/1.0/profiles/default",
  "/1.0/profiles/newprofile"
]

The jq .metadata is to show only the metadata section and not the full reply.

I get that the data in the tables is bound to change at some point. But even then it’s more likely stuff gets added or columns shuffled around. And still I could take care of that by defensive coding. But with the ASCII art tables everything gets so much more harder to parse, that’s the point I was making.

1 Like

These tables currently use just ASCII characters (because of https://github.com/olekukonko/tablewriter). Ideally, the tables should use Unicode characters so that they are visually pleasant to the eye.
I can envision some client configuration option to denote what style of table to show (plain, ASCII, Unicode style #1, Unicode style #2, Unicode with colors, etc).

But in your case, I wholeheartedly recommend to use the API. Whichever language you use, you can write functions that make the access to the API indistinguishable from parsing from the command line.