And example script for getting and setting OVS external-ids.
Since currently there is no nmcli support for these properties yet,
the script becomes more interesting.
This "example" is rather long, and it showcases less the usage of
libnm (which is rather trivial, with respect to configuring
NMSettingOvsExternalIDs). Instead, it aims to provide a useful
command line tool for debugging. Hence, it's mostly concerned with
an elaborate command line syntax and useful print output.
libnm supports verbose debug logging by setting "LIBNM_CLIENT_DEBUG"
environment variable. That mechanism uses g_printerr() (or g_print()).
When testing an application it's useful to combine printf debugging
with this debug logging. However, python's print() statement is
additionally buffered and not in sync with the logging functions that
libnm uses.
As far as I see, g_print() and g_printerr() is not accessible via
introspections/pygobject, probably because these are variadic functions.
Add nm_utils_print() to libnm. This ensures to use the same logging
mechanism as libnm.
We have:
- nm_utils_hashtable_cmp(): this does a full cmp of two hash
tables, with the intent to provide a stable sort order.
It thus takes a GCompareDataFunc() argument.
- nm_utils_hashtable_cmp_equal(): this is like nm_utils_hashtable_cmp(),
except that the caller won't get a compare value, only a boolean
value that indicates equality.
This was previously called nm_utils_hashtable_equal().
- nm_utils_hashtable_equal(): this takes a GEqualFunc function
for comparing the values for equality. It takes thus
a different kind of predicate, but otherwise is similar to
nm_utils_hashtable_cmp_equal().
This was previously called nm_utils_hash_table_equal().
Unify the naming of these functions.
These packages are also used during CI tests (in the checkpatch
stage). They are also used for formatting C/python code, and thus
useful for developing.
Install them as part of REQUIRED_PACKAGES script.
On one image we do extra work, like generating documentation (gitlab-pages).
The same image is currently also used for the "checkpatch" step. That step
checks code formatting using clang-format. The formatting depends on the
clang version, and we currently choose Fedora 33 as the desired version
for formatting.
It means, the "checkpatch" step requires Fedora 33. We could choose a
different image for generating pages and run check patch. However, that
might not be best. Just also generate the pages using Fedora 33.
All the steps of "checkpatch" test (except the last) check
the current tree for consistency. Those checks must always
pass.
Only the last step calls the "checkpatch-feature-branch.sh".
That script checks for common patterns, like avoiding g_assert()
(in favor of other assertion types). That last check only checks
the current patch, and there are many cases where the test is
known to fail (because these are just heuristics). As such, the
step that may fail should be called as last.
ci-templates encourages building specific containers that can be re-used:
- containers are re-used across pipelines, producing consistent results
- containers are re-used by contributors since they will use the upstream
containers for their MR, thus guaranteeing the same results.
Containers are automatically rebuild whenever the respective
FDO_DISTRIBUTION_TAG changes. This is particularly interesting now that
Docker Hub will introduce pull limits.
This CI script consists of a config file and a jinja2 template, simply
running 'ci-fairy generate-template' produces the .gitlab-ci.yml.
ci-fairy is part of the freedesktop.org ci-templates and can be pip
installed, see the check-ci-script job.
Functional changes to the previous script:
- new job: check-ci-script, verifies that our gitlab-ci.yml is the one
generated by the sources
- Added distributions:
- Fedora 33
- The actual work is now down by a set of scripts in .gitlab-ci/,
specifically:
- .gitlab-ci/build.sh is the previous do_build job
- .gitlab-ci/{fedora|debian}-install.sh are the previous {fedora|debian}_install jobs
symlinks are in place for centos and ubuntu
Why the scripts instead of steps in the CI? Easer to reading and
reproduce. With the containers being static, it's easy to pull one
locally and re-run the CI job to reproduce an issue. Having everything in a
single script makes that trivial.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/664
We can generate "generate-docs-nm-settings-nmcli.xml" by running "clients/cli/generate-docs-nm-settings-nmcli".
However, during cross compilation, that binary gets build in the target architecture,
it can thus not run to generate the XML.
Note that "--enable-gtk-doc" requires "--enable-introspection".
For generating "settings-docs.h" we (only) need introspection/pygobject.
We also have a pre-generated .in file that we can use if introspection
is not available. Since we have a pre-generated variant, it would be fine
to always use that one. However, we want to use generate the file if we
have the necessary dependencies, because thereby we can check whether
the pre-generated file is identical to what would be generated.
We have a similar problem with "generate-docs-nm-settings-nmcli.xml".
However there we don't need introspection, but merely being able to
execute a binary that we build. That does not work during cross
compilation, so we will honor "--enable-gtk-doc" flag to decide when
to generate the file.
For consistency, also adjust the condition for "settings-docs.h" to only
generate the file if we have "--enable-gtk-doc" (but not it we build
with "--enable-introspection" alone).
With glib2-2.67.0-1.fc34.x86_64.rpm, clang-11.0.0-2.fc34.x86_64.rpm, the
generated code emits a compiler warning:
libnm-core/tests/nm-core-tests-enum-types.c:17:7: error: passing 'typeof (*(&g_define_type_id__volatile)) *' (aka 'volatile unsigned long *') to parameter of type 'gsize *' (aka 'unsigned long *') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
if (g_once_init_enter (&g_define_type_id__volatile))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gthread.h:260:7: note: expanded from macro 'g_once_init_enter'
(!g_atomic_pointer_get (location) && \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get'
__atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
^~~~~~~~~~~~~~~~~
libnm-core/tests/nm-core-tests-enum-types.c:40:7: error: passing 'typeof (*(&g_define_type_id__volatile)) *' (aka 'volatile unsigned long *') to parameter of type 'gsize *' (aka 'unsigned long *') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
if (g_once_init_enter (&g_define_type_id__volatile))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gthread.h:260:7: note: expanded from macro 'g_once_init_enter'
(!g_atomic_pointer_get (location) && \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get'
__atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
^~~~~~~~~~~~~~~~~
libnm-core/tests/nm-core-tests-enum-types.c:63:7: error: passing 'typeof (*(&g_define_type_id__volatile)) *' (aka 'volatile unsigned long *') to parameter of type 'gsize *' (aka 'unsigned long *') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
if (g_once_init_enter (&g_define_type_id__volatile))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gthread.h:260:7: note: expanded from macro 'g_once_init_enter'
(!g_atomic_pointer_get (location) && \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get'
__atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
^~~~~~~~~~~~~~~~~
We could pass "-Wincompatible-pointer-types-discards-qualifiers" as CFLAGS
when building this file. However, we have a workaround in our "nm-glib-aux/nm-glib.h",
so we can instead include "nm-default.h". At first glance, that might look like
the less preferable solution. However, this file is only there for unit tests,
and we also include "nm-default.h" for other sources that are generated with
"glib-mkenums". So, doing it also for our tests becomes the preferable solution.
When including <glib.h>, it will always define G_LOG_DOMAIN if it
is not yet defined.
Usually we want to include "nm-default.h" as very first header. In that
case, <glib.h> is not yet included. Then the previous check #error works
well.
However, if we include "nm-default.h" in sources generated by
glib-mkenums, then the generator first already includes <glib.h>,
and thus defines G_LOG_DOMAIN. It does so for "libnm-core/nm-core-enum-types.c"
and "libnm/nm-enum-types.c", where the #error would not trigger.
But we will also include "nm-default.h" for "libnm-core/tests/nm-core-tests-enum-types.c".
That will start triggering this #error.
While in general we want to include "nm-default.h" first, we also need
to support cases where <glib.h> gets included first. Thus this error is
not useful. Remove it.
It's not strictly necessary, because contrary to g_atomic_pointer_get()
and g_atomic_pointer_compare_and_exchange(), glib's variant for the
setter is mostly fine.
Still, reimplement it, because we use typeof() eagerly and can thus add
more static checks than glib.
It seems it can happen that the service is not yet unregistered from the
D-Bus broker, even if we already reaped the PID.
/builds/NetworkManager/NetworkManager/tools/run-nm-test.sh --called-from-make /builds/NetworkManager/NetworkManager/build --launch-dbus=auto /builds/NetworkManager/NetworkManager/build/libnm/tests/test-nm-client
--- stdout ---
/libnm/device-added:
nmtst: initialize nmtst_get_rand() with NMTST_SEED_RAND=0
--- stderr ---
**
test:ERROR:../shared/nm-test-utils-impl.c:216:nmtstc_service_cleanup: assertion failed: (!name_exists(info->bus, "org.freedesktop.NetworkManager"))
Workaround by waiting a bit.
We now iterate the main GMainContext, unlike before. But that
should not cause any problems for the test.
Kernel does a auto-mtu adjusting process whenever a port is added/removed from
the bridge, this can cause issues when NM wants to explicitly set an MTU which is
equal to the bridge default one (1500) because if later a port is added with a
different MTU the kernel will assign the bridge that port's MTU resulting in the bridge
runtime configuration differing from the bridge's NM connection profile.
What we can do is to always apply the MTU manually for the bridge (if explicitly
set by the profile), after doing so the kernel won't modify the MTU anymore,
which is what we want, problem is that kernel won't actually apply the MTU
to the netdev if it's not actually changing so we first apply it to
MTU-1 and then to the desired value.
https://bugzilla.redhat.com/show_bug.cgi?id=1778590
Signed-off-by: Antonio Cardace <acardace@redhat.com>
Add a parameter to the 'link_add()' virtual function so that
the MTU will be configured (via netlink) by the kernel when
creating the link.
https://bugzilla.redhat.com/show_bug.cgi?id=1778590
Signed-off-by: Antonio Cardace <acardace@redhat.com>
- we commonly use "int addr_family" as parameters to functions.
But then inside the function, we often need to do something for
IPv4 or IPv6 specifically. Instead of having lots of redundant
"if (addr_family == AF_INET)" checks, prefer to have a variable
IS_IPv4 and/or use NM_IS_IPv4() macro.
- don't make the "IS_IPv4" variable a gboolean but an int. gboolean
is a typedef for int, so it's in practice exactly the same. However,
we use "IS_IPv4" as index to arrays of length 2, where at position
"1" we have the value related to IPv4. Using a gboolean to index
an array is a bit odd. Maybe a "int" is preferable here.
This is more about doing consistently one or the other. There are
no strong reasons to prefer gboolean or int.
Apparently it is not actually used, but the function implements
a return value for AF_UNSPEC, while also asserting that the addr_family
is AF_INET/AF_INET6. Drop the assertions.