With --color=auto, coloring is enabled based on the .enable/.disable
termcolors files.
Likewise, when we enable coloring, we parse the color palette from the
.schem termcolors files.
The termcolors files are searched by finding the best match depending
on the terminal and application name. Note, that if we find a matching
file like "nmcli@xterm.enable" we still allow loading the palette from
a less specific file like "nmcli.schem" and vice versa. That was already
done before.
Previously, the search was done by calling several layers of functions, and having
in/out arguments "color_option" and "p_palette_buffer". in/out paramters
here seems confusing to me, as they are state that gets modified and carried
along.
Instead, rework the functions to clearly separate between input
and output arguments.
Also, in the auto-case, check_colors() now first determines whether
coloring is enabled, before even starting loading the palette.
This avoids loading the palette until we are sure that we need it.
The NmCli variables is essentially a global variable of *everything*.
The set_color() function and its helpers only need a particular
part of it. Instead, of passing the entire global state to them,
only pass what they need.
It makes it clearer which parts are actually relevant. Turns out,
it only actually touches a resonable small part of the global state.
use nmc_print() for the job.
Also, localize non-terse output.
Also, fix bug with
$ nmcli c s /org/freedesktop/NetworkManager/ActiveConnection/1
if active connection #1 is invisible to the user.
Also, previously, fill_output_active_connection() wrongly tries to
write to a field that doesn't exist:
set_val_strc (arr, 13-idx_start, s_con ? nm_setting_connection_get_slave_type (s_con) : NULL);
The output of `nmcli connection show` contains also information about
whether the profile is currently active, for example the device and
the current (activation) state.
Even when a profile can be activated only once (without supporting
mutiple activations at the same time), there are moments when a
connection is activating and still deactivating on another device.
NetworkManager ensures in the case with single activations that
a profile cannot be in state "activated" multiple times. But that
doesn't mean, that one profile cannot have multiple active connection
which reference it. That was already handled wrongly before, because
`nmcli connection show` would only search the first matching
active-connection. That is, it would arbitrarily pick an active
connection in case there were multiple and only show activation
state about one.
Furthermore, we will soon also add the possibility, that a profile can be
active multiple times (at the same time). Especially then, we need to
extend the output format to show all the devices on which the profile is
currently active.
Rework printing the connection list to use nmc_print(), and fix various
issues.
- as discussed, a profile may have multiple active connections at each time.
There are only two possibilities: if a profile is active multiple
times, show a line for each activation, or otherwise, show the
information about multiple activations combined in one line, e.g. by
printing "DEVICE eth0,eth1". This patch, does the former.
We will now print a line for each active connection, to show
all the devices and activation states in multiple lines.
Yes, this may result in the same profile being printed multiple times.
That is a change in behavior, and inconvenient if you do something
like
for UUID in $(nmcli connection show | awk '{print$2}'); do ...
However, above is anyway wrong because it assumes that there are no
spaces in the connection name. The proper way to do this is like
for UUID in $(nmcli -g UUID connection show); do ...
In the latter case, whenever a user selects a subset of fields
(--fields, --get) which don't print information about active connections,
these multiple lines are combined. So, above still works as expected,
never returning duplicate UUIDs.
- if a user has no permissions to see a connection, we previously
would print "<invisible> $NAME". No longer do this but just print
the ID was it is reported by the active-connection. If the goal
of this was to prevent users from accidentally access the non-existing
connection by $NAME, then this was a bad solution, because a script
would instead try to access "<invisible> $NAME". This is now solved
better by hiding the active connection if the user selects "-g NAME".
- the --order option now sorts according to how the fields are shown.
For example, with --terse mode, it will evaluate type "802-11-wireless"
but with pretty mode it will consider "wifi". This may change the
ordering in which connections are shown. Also, for sorting the name,
we use g_utf8_collate() because it's unicode.
The present version of the specification is somewhat unclear at times,
Unclear points were discussed with the maintainers [1] and probably
some new version will address those.
https://www.spinics.net/lists/util-linux-ng/msg15222.html
Until then here's how the implementation copes with ambiguities
(after the discussion with util-linux maintainers):
1.) It is unclear whether multiple .schem files should override each
other or be merged. We use the overriding behavior -- take the
highest priority one and ignore the rest.
2.) We assume "name.schem" is more specific than "@term.schem".
3.) We assume the "Color name" are to be used as aliases for the color
sequences and translate them to ANSI escape sequences.
4.) The "Escape sequences" are of no use since the specification
pretty much assumes an ANSI terminal and none of the sequences make
any sense in ANSI color codes. We don't support them.
accept that.
5.) We don't implement TERMINAL_COLORS_DEBUG because it's unspecified
what should it do.
This basically replaces the (NMMetaTermColor, NMMetaTermFormat) combo
with NMMetaColor that describes the colored element semantically as
opposed to storing the raw attributes.
A (currently static) paletted is used to translate the semantic color
code to the actual ANSI controle sequence. This matches what
terminal-colors.d(5) schemes use, making it convenient to implement
customizable palettes.
This actually makes very little difference at the moment, but will make
things more confortable later on, when the logic of enabling/disabling
coloring will involve terminal-colors.d(5).
Instead of deciding whether to use colors lazily with use_colors(), it's
done very early on nmcli initialization and a boolean use_colors field
is stored in the NmcConfig instance instead of the raw tristate option
of NmcColorOption type (which is now confined to nmcli.c).
Wherever the NmcColorOption was used previously, the whole NmcConfig
instance is passed around. That might seem pointless (since only the
use_colors boolean is actually used at the moment), but will be utilized
to pass around the actual color palette in future.
It's undocumented, useless, somewhat expensive in volume of code and
probably just downright stupid. We'll get a more general way to set
colors.
Hacking in some code to keep this working wouldn't be too difficult, but
it seems entirely pointless.
Add a new 'overview' command line option to make the output more
compact and display only properties that have non-default
values. Currently the option has only effect for the "connection show
$CON" sub-command.
$ nmcli -o connection show wifi-home
connection.id: wifi-home
connection.uuid: 8308c425-f2a7-4021-9afc-37bde7253c6d
connection.type: 802-11-wireless
connection.timestamp: 1519264421
connection.permissions: user:me
802-11-wireless.ssid: home
802-11-wireless.mode: infrastructure
802-11-wireless-security.key-mgmt: wpa-psk
802-11-wireless-security.auth-alg: open
ipv4.method: auto
ipv6.method: auto
https://bugzilla.redhat.com/show_bug.cgi?id=1434527
Hook the signal handlers right before the main loop. Prior to that
the default handlers are good enough and our one crashes (due to
loop being instantialized).
Also, set the return value properly to indicate a termination by a
signal.
Next we will use siphash24() instead of the glib version g_direct_hash() or
g_str_hash(). Hence, the "nm-utils/nm-hash-utils.h" header becomes very
fundamental and will be needed basically everywhere.
Instead of requiring the users to include them, let it be included via
"nm-default.h" header.
Replace the usage of g_str_hash() with our own nm_str_hash().
GLib's g_str_hash() uses djb2 hashing function, just like we
do at the moment. The only difference is, that we use a diffrent
seed value.
Note, that we initialize the hash seed with random data (by calling
getrandom() or reading /dev/urandom). That is a change compared to
before.
This change of the hashing function and accessing the random pool
might be undesired for libnm/libnm-core. Hence, the change is not
done there as it possibly changes behavior for public API. Maybe
we should do that later though.
At this point, there isn't much of a change. This patch becomes
interesting, if we decide to use a different hashing algorithm.
This makes it a lot more convenient to deal with long outputs (such as
"nmcli c show id ...").
The implementation is essentially jacked from systemd. The bugs are
mine.
That allows for the property list to contain derived
property types. Also, the list can be directly passed
off as a "const NMMetaAbstractInfo *const*" list.
The show-secrets flag can be toggled in edit mode
nmcli> nmcli show-secrets yes
There is no point in tracking two separate flags for it. Inside
edit mode, when the user toggles the show-secrets flag, it should
overwrite the command line option.
These two flags can be merged.
The show-secret property is basically a part of the current
configuration, relevant during printing. It will be passed
on to nmc_print(), and hence must be part of NmcConfig.
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.
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
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.
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.
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.
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.