We already have
- data sources (nm_cli, connections or settings)
- meta data information how to access the data sources (NMMetaAbstractInfo,
NmcMetaGenericInfo, NMMetaPropertyInfo)
Add now a generic way to output cli data using nmc_print(). It gets a
list of data-sources (@targets) and a list of available fields (meta
data). It also gets cli configuration (NmcConfig) and field selector
strings (@field_str).
Based on that, it should output the desired data.
This is intended to replaces the previous approach, where functions like
show_nm_status() have full knowledge about how to access the data and
create an intermediate output format (NmcOutputData, NmcOutputField)
that was printed via print_data().
show_nm_status() contained both knowledge about the data itself (how to
print a value) and intimate knoweledge about the output intermediate
format. Also, the intermediate format is hard to understand. For
example, sometimes we put the field prefix in NmcOutputField at index 0
and via the NmcOfFlags we control how to output the data.
Clearly separate the responsibilities.
- The meta data (NmcMetaGenericInfo) is only concerned with converting
a data source to a string (or a color format).
- the field selection (@field_str) only cares about parsing the list
of NMMetaAbstractInfo.
- _print_fill() populates a table with output values and header
entries.
- _print_do() prints the previously prepared table.
The advantage is that if you want to change anything, you only need to
touch a particular part.
This is only a show-case for `nmcli general status`. Parts are still
un-implemented and will follow.
This changes behavior for --terse mode: the values are now no longer
translated:
$ LANG=de_DE.utf8 nmcli -t --mode multiline general
Depending on the get_type argument, we don't only want
to return strings, but arbitrary pointers.
The out_to_free argument still makes sense, but depending on
the get-type you must know how to free the pointer.
When generating output data, nmcli iterates over a list of
property-descriptors (nmc_fields_ip4_config), creates an intermediate
array (output_data) and finally prints it.
However, previously both the meta data (nmc_fields_ip4_config) and
the intermediate format use the same type NmcOutputField. This means,
certain fields are relevant to describe a property, and other fields
are output/formatting fields.
Split this up. Now, the meta data is tracked in form of an NMMetaAbstractInfo
lists. This separates the information about properties from intermediate steps
during creation of the output.
Note that currently functions like print_ip4_config() still have all the
knowledge about how to generate the output. That is wrong, instead, the
meta data (NMMetaAbstractInfo) should describe how to create the output
and then all those functions could be replaced. This means, later we want
to add more knowledge to the NMMetaAbstractInfo, so it is important to
keep them separate from NmcOutputField.
Embed a @meta_type structure in NMMetaSettingInfoEditor and
NMMetaPropertyInfo. This allows to make the NMMeta*Info instances
themself to become generic and they can be passed around as generic
NMMetaAbstractInfo types.
For one, the embedded NMMetaType pointer can be used to determine
of which type a NMMetaAbstractInfo instance is. On the other hand,
the NMMetaType struct can be extended to be a VTable to provide
generic access to the type.
In the end, both NMMetaSettingInfoEditor and NMMetaPropertyInfo are
conceptionally very similar: the describe a certain type and provide
accessors.
In nmcli we have yet another NMMetaAbstractInfo type: NmcOutputField
will be modified to become another implementation of meta data (it
already is, it just cannot be used interchangable with the other
types).
Also, embed the NMMetaSettingInfoEditor in the NMMetaPropertyInfo
instance. This allows from a given NMMetaPropertyInfo to retrieve it's
parent NMMetaSettingInfoEditor.
"nm-meta-setting-desc.h" contains static type description, vtable and (internal)
accessor functions. Add accessor functions that operate on top of the type description
to "nm-meta-setting-access.h".
This check requires additional information about the environment, that
is about the present connections in NMClient.
"nm-meta-setting-desc.c" should be independent from the libnm D-Bus
cache, hence move this code to "settings.c".
The lower layers are concerned with handling settings. They should not
be aware of how to notify about warnings. Instead, signal them via
the warn_fcn() hook.
Options dependant on specific commands (e.g., nmcli connection show
--active) are now allowed to be processed by the next_arg() function.
This would allow autocompletion to expand options belonging to specific
command first, and then global ones.
Note that global options ("--ask" and "--show-secrets") will be auto-completed
everywhere but only if at least a '-' is passed. Command specific ones
(--temporary, --active, --order) will be auto-completed only after the command
they belongs to but without requiring the user to pass a heading '-'.
Example:
'nmcli connection show -a'
will expand '-a' into '--active', but
'nmcli connection add -a`
will expand '-a' into '--ask' (as it is a global option)
This commit fixes also autocompletion for:
nmcli connection modify --temporary
This happens when the connection is in "activating" state and
the connection is a master one waiting for slaves: "check_activated()"
is called by the active_connection_state_cb() and device_state_cb() callbacks.
If the device has already moved to a state >= NM_DEVICE_STATE_IP_CONFIG, the
call to active_connection_state_cb() will end calling
activate_connection_info_finish(), freeing the "info" object. The subsequent
call to device_state_cb() will result in accessing the freed "info".
Just call check_activated() once after registering the
active_connection_state() and device_state_cb() callbacks.
Before commit a63c4d0824 ("cli: use designated initializers for
setting NmcOutputField fields") each field had a @name and a
@name_l10n , which were equal for all properties except for wifi
IN-USE:
{"IN-USE", N_("*")}, /* 15 */
The commit removed @name_l10n so now the displayed name is equal to
the field name. But now:
$ nmcli device wifi list
Error: 'device wifi': invalid field 'IN-USE'; allowed fields:
NAME,SSID,SSID-HEX,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,
WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,*,DBUS-PATH
The new field name should be 'IN-USE' and not '*', otherwise scripts
doing "-f IN-USE" will break. As a side effect we now show 'IN-USE'
instead of '*' in the column header, which seems easier to understand:
IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY
* default Infra 5 54 Mbit/s 71 ▂▄▆_ WPA2
guest Infra 1 54 Mbit/s 62 ▂▄▆_ WPA2
Fixes: a63c4d0824
We should not violate the global data to track the output data
while it is constructed and printed.
Most of the time, we actually clear the output data anyway --
either before constructing it, or after printing it.
In some cases we didn't, but I think that is a bug. It's really
hard to keep track of this.
The output data should belong to a certain scope and get destroyed
afterwards. Passing it around is very confusing. Don't do that.
To better understand which part of the code have side effects,
split print_data() in a part that mutilates the input array
and a part that only prints.
Don't cast const strings to non-const. And don't track
whether to free a variable in a boolean. Instead, assign
ownership to variables that get destroyed when the function
returns.
The NmCli structure is passed around everywhere and contains all
the state of the program. It is very hard to follow which parts
are used where.
Split out more configuration options to a NmcConfig field. This field
is mostly immutable, and modified at particular places that now can be
easily found.
nmc contains all options and collects output data. It is very hard to
understand what it does. Start splitting it up, and pass arguments along
-- as needed.
Otherwise, changing the structure is difficult because it all depends
on the order (and you don't immdiately see which field is used where).
Also, drop the name_l10n field.
These functions are only used by nm-meta-setting-desc.c. Make them internal.
Unfortunately, they are part of "common.h" which cannot be used without
the rest of nmcli. Still todo.
This part contains static functions and variables to describe
settings. It is distinct from the mechanism to use them, or
access them.
Split it out.
It still uses clients/cli/common.h and clients/cli/utils.h
which shall be fixed next.
They will be moved out of nmcli as they are generally useful.
Even if they happen to be used only inside nmcli, there should
be a better separation between logic (nmcli) and setting decriptions.
Mostly these strings are static. In same cases they are generated
however. Instead of caching them in a static variable, return them
to the caller.
And belatedly fix invoking describe_fcn().
settings.c basically consists of property-type structures and *a lot* of
accessors. All these accessors share the same argument list.
It is very repetitive to specify it over and over again. Also, there
are so many arguments that one is compelled to wrap the lines. All
in all it results in a lot of noise that takes the eye from the important
code.
Also, the argument list is expected to change, so we possibly only
have to change one place.