summaryrefslogtreecommitdiff
path: root/include
Commit message (Collapse)AuthorAge
* YAML consolidation prelude: new YAML dump APIs (FR-702) (#251)Simon Chopin2022-01-17
| | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce a couple of APIs that are needed for the various YAML consolidation efforts. Note that this is technically an API break, but the function that is removed has never been part of a release, so this should be OK. COMMITS: * lib:netplan: rework API to dump the state into a file descriptor This allows for more flexibility than using filenames. The implementation is split in two functions to allow for future variants, i.e. updating an existing netplan configuration tree. This patch is technically an API break but the removed API was never released. V2: - use a helper function netplan_state_has_nondefault_globals() - fix the write_netplan_conf_full behavior on empty state to not create an empty file - DRASTICALLY simplify the implementation of netplan_state_dump_yaml(), fixing a leak by not using a new list in the first place * lib:yaml-helpers: add helpers to produce yaml NULL values * lib:util: new helper function to dump a yaml subtree This API is also using file descriptors for flexibility. The idea is to be able to copy only part of a YAML document based on a "prefix", that is subsequent keys into YAML maps, separated by '\t' characters. V2: add some comments and use better names for the static helpers
* lib: use an explicit parser context (#233)Simon Chopin2021-11-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of directly writing into the final network state, use a separate global parser object to store any intermediate data needed during parsing. This allows us to ensure that the client can only see valid configurations, as the parser is opaque to the client, who then must call our functions to import and validate the data into the final network state. Since the public API doesn't allow us to pass around some context, we still store a static object to use in those APIs, but all the internal functions shouldn't touch any external data. This PR depends on #229 and #227 and is only a prequel to the proper YAML parser unification work, which will start with the removal of the current parsing API, replaced by one based on explicitly allocated states, in conjunction with the #232 work. To make things easier, the latter PR has been added as a dependency for this one. It also picked up a dependency on #234 along the way :) Only the commits after the merge commit are part of the PR proper, the rest are from the dependencies. COMMITS: * lib: new functions *_clear to safely clear heap-allocated complex structs We already have the functions to actually free the objects, these helpers just wrap those to also clear up the *pointer* and nullifying it. These functions are going to be used in the parser code to clear intermediate state, notably on the error paths. Function names, signature and implementations are heavily inspired by g_datalist_clear(). V2: rename the functions to match the new scheme [prefix_]type_action * parse: clear the cur_addr_options pointer once the parsing is done Keeping a pointer around after we've transferred ownership of the data to a netdef is a recipy for disaster, as we have no way of knowing if we're still responsible for cleaning up the NetplanAddressOptions object. * lib: yaml: change the error goto label to err_path `error` is usually a GError** argument, and the new name is just as legible. * lib: write_netplan_conf_full: use an early-return This allows us to shift the code left, make it easier to read. * lib: util: netplan_delete_connection: clear the state at the beginning The function is supposed to work on an already empty state, as it parses a whole tree and validates it afterwards. We thus clear it explicitly. This is a latent bug that might become apparent should the validation be a little more stringent, such as redefinition of already existing netdefs. * tests: clear the global state in teardowns to expose inter-test order dependency Some tests were relying on the state having been cleared in a previous state, which isn't necessarily the case. * cli/utils: force a full parse cycle before extracting ids by devtype While the current approach works for now, it'll break when we separate parser state and global state, until we do the actual validation. * lib: use an explicit parser context Instead of directly writing into the final network state, use a separate global parser object to store any intermediate data needed during parsing. This allows us to ensure that the client can only see valid configurations, as the parser is opaque to the client, who then must call our functions to import *and validate* the data into the final network state. Since the public API doesn't allow us to pass around some context, we still store a static object to use in those APIs, but all the internal functions shouldn't touch any external data. V2: * Remove stray cur_filename global variable * Fix some formatting * Rename 'done' field to 'parsed_defs' * Reduced the nocov zone * libnetplan: rewrite netplan_finish_parse using explicit states The netplan_finish_parse implementation is moved to our ABI attic, abi_compat.c, and is now a simple wrapper around netplan_state_import_parser_results, which is the new function used to import into a Netplan state the results of a parsing operations. As before, the idea is to maintain a constantly valid Netplan state, so this function does validation before import. * lib: expose new functions to generate YAML from Netplan state or defs The old functions have been rewritten as wrappers around the new APIs V2: * Add some header comments to the new functions * parse-nm: new API using the separate parser state * lib: add accessors to be able to reach filename from netdef ID * lib: rewrite process_input_file and process_yaml_hierarchy using the new API scheme There are no process_input_file() replacement as it can very well be written by the client code. process_yaml_hierarchy() has been replaced by a function in utils, netplan_parser_load_yaml_hierarchy(), which leaves the error policy up to the client code rather than calling exit(). The old versions have been moved to abi_compat.c and reimplemented to keep their previous semantics. * lib: move _write_netplan_conf to the abi_compat.c file This function is only there for legacy reasons, and should be replaced by a normalized API. * lib: netplan_get_filename_by_id: move to abi_compat.c This is an old API. The ABI compat version is entirely reimplemented using public, up-to-date functions. * lib: util: reimplement netplan_delete_connection with the new APIs This new implementation does away with global state, creating its own local state instead. V2: fix formatting * netplan:utils: mark the exception path of the devtype iter as nocover * netplan/cli/utils: move the iter ABI check in the wrapper class This makes it possible to use the wrapper class in autonomy, and remove the implicit dependency between the netplan_get_ids_for_devtype tests and the _NetdefIdIterator tests. The latter would crash if run before the former, as the ctypes bindings wouldn't have been initialized. * lib: networkd: fix a stray call to an old API THis call meant that the network file was generated using the global state as reference instead of the local np_state, making things such as the VLAN feature basically useless. * generate: migrate to the new libnetplan APIs This allows us to do proper cleanup on error cases. Note that since generate was the only consumer of some of the legacy APIs, those endpoints are not hit by the testsuite anymore and are thus marked as ignored by the coverage calculations.
* lib: introduce the notion of NetplanState (#232)Simon Chopin2021-10-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This would be a structure holding all the data used to define a complete network setup in Netplan. At this moment there are no guarantee of coherence or validation of the validation, though. We use some linker tricks to keep the previous globals `netdef`, `netdef_ordered` and `global_ovs_config` visible in the ABI, even though they now actually point to fields within a global state instance that is there only for this compatibility purpose. Note that the constructor, destructor and netdef accessors aren't implemented yet. This is mostly because there are no consumers for this API yet, and I'd like to get this commit into the mainline as is, which means retaining 100% code coverage... ¯\_(ツ)_/¯ V2: * rename the nps arguments to np_state * use a netplan_state_* naming scheme for all functions pertaining to the new structure * Add placeholder implementations for netplan_state_{new,clear} * Add a comment in netplan_state_reset regarding the ownership of netdef objects * Remove superfluous headers in abi_compat.c * Remove the dependency on the error-code-flow branch V3: * Disable LCOV coverage on the placeholder functions
* API/ABI: restrict the symbol export to a determined public API (#227)Simon Chopin2021-09-30
The goal of this PR is to properly determine what the public interface of libnetplan is. There is potentially a bit of ABI breakage, as symbols now default to hidden status unless explicitly marked otherwise, and said marking was done manually by looking at the current consumers I had on my system and trying to fill in the blanks. The API, on the other hand, has been conscientiously broken, as most of what was exposed in the headers are now safely hidden away in our internal headers. This is by design, and AFAICT should not break existing code. This PR depends on #230, as denoted by the merge commit in there. It should make independent review a bit easier :). Given the fact that the main purpose of this PR is to limit the amount of symbols we export, we can safely assume that strictly speaking, there is ABI breakage. However, the whole point was to only expose the symbols that are in actual use out there in the real world. As usual, the patchset has been edited expecting a review commit by commit, as the whole diff can be a bit daunting. COMMITS: * libnetplan: rework netplan,parse{-nm},util.h as public headers This work involves splitting out some things from those headers into new internal headers, and moving definitions around so that the public headers are as self-contained as possible. For the new internal headers, I decided to have a big "types.h" header containing all the types used in a network definition. In itself, these types aren't related to parsing except that the parser module is the only producer, so I decided they could live on their own. This is also the place where type-specific helpers can be found, such as reset_netdef(). The various macros used to generate YAML were gathered up from both source headers into a new yaml-helpers.h header, whereas the various global state definitions were split off into their own headers, making it easier to spot which areas of the code still rely on global state. The remainder functions were moved into util-internal.h This allows us to minimize the API exposed to the outside world. V2: * Remove the extraneous struct net_definition line, as it is redundant with the typedef * Normalize all the symbol declarations to have the symbol name at the beginning of their own line, at least in the headers we touched. V3: * Remove extraneous stdbool.h header * Split parse-helpers.h into yaml-helpers.h and util-internal.h * Add uuid as a dependency of the dbus generator to make it compile with the new lay of the land. * Add some missing copyright headers * libnetplan: Properly mark the lib/bin interface This patch cleanly marks which functions/objects are part of the public library API, and which are meant to be consumed by our own binaries. In order to reduce as much as possible the ABI dependencies between our binaries and the library, I move the various generator modules into the library as it make sense for them to access directly the objects. On the other hand, both generate.c and dbus.c should be relatively trivial to change to use getters and setters instead of direct structure access. Those changes will be the object of later patches. V3: * Makefile: consolidate the pkg-config calls and add back the LDFLAGS variable * Normalize the touched function declarations to always have the symbol name at the start of the line. * libnetplan: add back ABI compatibility Re-export (and recreate) various symbols that are needed by the `generate` binary as shipped in the Ubuntu package 0.103-0ubuntu5 I have chosen a separate marker for those, in order to distinguish what was exposed deliberately and by accident. That way, if we need to do a SONAME bump, we can clean up the symbols marked with NETPLAN_ABI. V3: * Normalize the declarations that are touched to always have the symbol name at the start of the line * libnetplan: export Python-used symbols as internal * libnetplan: hide all symbols by default Only those marked by NETPLAN_{PUBLIC,INTERNAL,ABI} will be available to the loader.