diff --git a/.github/workflows/autopkgtest.yml b/.github/workflows/autopkgtest.yml
index 44991580a..60cca520a 100644
--- a/.github/workflows/autopkgtest.yml
+++ b/.github/workflows/autopkgtest.yml
@@ -33,7 +33,6 @@ jobs:
# it's needed (will be auto-loaded) by routing.test_vrf_basic
- name: Install dependencies
run: |
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
sudo apt install autopkgtest ubuntu-dev-tools devscripts openvswitch-switch linux-modules-extra-$(uname -r)
# work around LP: #1878225 as fallback
@@ -46,6 +45,12 @@ jobs:
pull-lp-source netplan.io
cp -r netplan.io-*/debian .
rm -r debian/patches/ # clear any distro patches
+ # usrmerge-fix
+ mkdir debian/extra
+ touch debian/extra/PLACEHOLDER
+ echo "../extra/PLACEHOLDER usr/lib/netplan/PLACEHOLDER" >> debian/extra/PLACEHOLDER
+ sed -i 's|rm debian/tmp/lib/netplan/generate|sh -c "mkdir -p debian/tmp/usr/lib/systemd/system-generators; rm -rf debian/tmp/lib; ln -sf /usr/libexec/netplan/generate debian/tmp/usr/lib/systemd/system-generators/netplan"|' debian/rules
+ # usrmerge-fix-end
TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) # find latest (stable) tag
REV=$(git rev-parse --short HEAD) # get current git revision
VER="$TAG+git~$REV"
@@ -56,6 +61,5 @@ jobs:
# cmocka/pytest/rich/ethtool until they become proper test-deps
# The network-manager PPA is used here temporally due to a bug with veths and network-manager 1.36. See LP: #2032824
autopkgtest . \
- --setup-commands='apt -y install ethtool python3-rich python3-pytest python3-pytest-cov python3-cffi libpython3-dev libcmocka-dev' \
--setup-commands='sudo add-apt-repository -y -u -s ppa:danilogondolfo/network-manager' \
-U --env=DPKG_GENSYMBOLS_CHECK_LEVEL=0 --env=DEB_BUILD_OPTIONS=nocheck -- lxd autopkgtest/ubuntu/jammy/amd64
diff --git a/.github/workflows/build-abi.yml b/.github/workflows/build-abi.yml
index 4262ce80a..d7f993eb0 100644
--- a/.github/workflows/build-abi.yml
+++ b/.github/workflows/build-abi.yml
@@ -22,18 +22,17 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
# Installs the build dependencies
# Always include phased updates (LP: #1979244)
- name: Install build depends
run: |
echo "APT::Get::Always-Include-Phased-Updates \"true\";" | sudo tee /etc/apt/apt.conf.d/90phased-updates
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
- #sudo apt install lcov python3-coverage curl
- sudo apt install abigail-tools meson python3-coverage python3-pytest python3-pytest-cov python3-cffi libpython3-dev
- sudo apt build-dep netplan.io
+ sudo apt install abigail-tools ubuntu-dev-tools devscripts equivs
+ pull-lp-source netplan.io
+ mk-build-deps -i -B -s sudo netplan.io-*/debian/control
# Runs the build
- name: Run build
diff --git a/.github/workflows/check-address-sanitizer.yml b/.github/workflows/check-address-sanitizer.yml
index 134b36afe..f9fdfec48 100644
--- a/.github/workflows/check-address-sanitizer.yml
+++ b/.github/workflows/check-address-sanitizer.yml
@@ -20,15 +20,15 @@ jobs:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install build depends
run: |
echo "APT::Get::Always-Include-Phased-Updates \"true\";" | sudo tee /etc/apt/apt.conf.d/90phased-updates
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
- sudo apt -y install python3-rich python3-coverage python3-pytest python3-pytest-cov curl meson gcovr expect libcmocka-dev python3-cffi libpython3-dev
- sudo apt -y build-dep netplan.io
+ sudo apt -y install curl expect ubuntu-dev-tools devscripts equivs
+ pull-lp-source netplan.io
+ mk-build-deps -i -B -s sudo netplan.io-*/debian/control
- name: Run unit tests
run: |
diff --git a/.github/workflows/check-coverage.yml b/.github/workflows/check-coverage.yml
index b06e87abf..c3ba9cb19 100644
--- a/.github/workflows/check-coverage.yml
+++ b/.github/workflows/check-coverage.yml
@@ -26,10 +26,11 @@ jobs:
- name: Install build depends
run: |
echo "APT::Get::Always-Include-Phased-Updates \"true\";" | sudo tee /etc/apt/apt.conf.d/90phased-updates
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
- sudo apt install python3-rich python3-coverage python3-pytest python3-pytest-cov curl meson gcovr expect libcmocka-dev python3-cffi libpython3-dev
- sudo apt build-dep netplan.io
+ sudo apt install curl expect ubuntu-dev-tools devscripts equivs gcovr
+ pull-lp-source netplan.io
+ mk-build-deps -i -B -s sudo netplan.io-*/debian/control
+ rm -rf netplan.io-*/
wget http://archive.ubuntu.com/ubuntu/pool/universe/g/gcovr/gcovr_5.2-1_all.deb
sudo dpkg -i gcovr*.deb # we need newer gcovr to make the gcovr.cfg:exclude setting work
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index e6755111d..02a763e39 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -39,7 +39,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml
index f33977ea2..38a613d58 100644
--- a/.github/workflows/coverity.yml
+++ b/.github/workflows/coverity.yml
@@ -10,13 +10,14 @@ jobs:
runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install dependencies
run: |
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
+ echo "APT::Get::Always-Include-Phased-Updates \"true\";" | sudo tee /etc/apt/apt.conf.d/90phased-updates
sudo apt update
- sudo apt -y build-dep netplan.io
- sudo apt -y install libcmocka-dev meson python3-pytest curl python3-cffi libpython3-dev
+ sudo apt -y install curl
+ pull-lp-source netplan.io
+ mk-build-deps -i -B -s sudo netplan.io-*/debian/control
- name: Download Coverity
run: |
curl https://scan.coverity.com/download/cxx/linux64 --no-progress-meter --output ${HOME}/coverity.tar.gz --data "token=${{ secrets.COVERITY_TOKEN }}&project=Netplan"
diff --git a/.github/workflows/debci.yml b/.github/workflows/debci.yml
index 3c47f2c5a..f20e9083f 100644
--- a/.github/workflows/debci.yml
+++ b/.github/workflows/debci.yml
@@ -21,7 +21,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- run: |
git fetch --unshallow --tags
# Install openvswitch-switch to make the OVS integration tests work
@@ -29,7 +29,6 @@ jobs:
# it's needed (will be auto-loaded) by routing.test_vrf_basic
- name: Install dependencies
run: |
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
sudo apt install debci lxc lxc-templates debian-archive-keyring autopkgtest ubuntu-dev-tools devscripts linux-modules-extra-$(uname -r) #openvswitch-switch
# See: https://discourse.ubuntu.com/t/containers-lxc/11526 (Apparmor section)
@@ -46,10 +45,11 @@ jobs:
- name: Prepare test
run: |
# pull-debian-source netplan.io # snapshot.debian.org is not up-to-date
- V=$(rmadison -u debian -s unstable netplan.io | cut -d"|" -f2 | xargs)
+ V=$(rmadison -u debian -s unstable netplan.io | tail -n1 | cut -d"|" -f2 | xargs)
dget -u "https://deb.debian.org/debian/pool/main/n/netplan.io/netplan.io_$V.dsc"
cp -r netplan.io-*/debian .
rm -r debian/patches/ # clear any distro patches
+ sed -i 's|rm debian/tmp/lib/netplan/generate|# DELETED|' debian/rules
TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) # find latest (stable) tag
REV=$(git rev-parse --short HEAD) # get current git revision
VER="$TAG+git~$REV"
@@ -58,4 +58,5 @@ jobs:
run: |
# using --setup-commands='apt -y install ...' temporarily to install
# (test-/build-) deps until they become part of the packaging
- sudo autopkgtest . -U --env=DPKG_GENSYMBOLS_CHECK_LEVEL=0 --env=DEB_BUILD_OPTIONS=nocheck --setup-commands='apt -y install python3-cffi libpython3-dev' -- lxc autopkgtest-testing-amd64 || test $? -eq 2 # allow OVS test to be skipped (exit code = 2)
+ sudo autopkgtest . \
+ -U --env=DPKG_GENSYMBOLS_CHECK_LEVEL=0 --env=DEB_BUILD_OPTIONS=nocheck -- lxc autopkgtest-testing-amd64 || test $? -eq 2 # allow OVS test to be skipped (exit code = 2)
diff --git a/.github/workflows/network-manager.yml b/.github/workflows/network-manager.yml
index 0140e0dc9..ce5e39af8 100644
--- a/.github/workflows/network-manager.yml
+++ b/.github/workflows/network-manager.yml
@@ -33,7 +33,6 @@ jobs:
# it's needed (will be auto-loaded) by routing.test_vrf_basic
- name: Install dependencies
run: |
- sudo sed -i '/deb-src/s/^# //' /etc/apt/sources.list
sudo apt update
sudo apt install autopkgtest ubuntu-dev-tools devscripts openvswitch-switch linux-modules-extra-$(uname -r)
- name: Prepare test
@@ -41,6 +40,12 @@ jobs:
pull-lp-source netplan.io
cp -r netplan.io-*/debian .
rm -r debian/patches/ # clear any distro patches
+ # usrmerge-fix
+ mkdir debian/extra
+ touch debian/extra/PLACEHOLDER
+ echo "../extra/PLACEHOLDER usr/lib/netplan/PLACEHOLDER" >> debian/extra/PLACEHOLDER
+ sed -i 's|rm debian/tmp/lib/netplan/generate|sh -c "mkdir -p debian/tmp/usr/lib/systemd/system-generators; rm -rf debian/tmp/lib; ln -sf /usr/libexec/netplan/generate debian/tmp/usr/lib/systemd/system-generators/netplan"|' debian/rules
+ # usrmerge-fix-end
echo "3.0 (native)" > debian/source/format # force native build
TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) # find latest (stable) tag
REV=$(git rev-parse --short HEAD) # get current git revision
@@ -54,7 +59,7 @@ jobs:
with:
docker-image: ubuntu:mantic
buildpackage-opts: --build=binary --no-sign
- extra-build-deps: python3-cffi libpython3-dev
+ #extra-build-deps: python3-cffi libpython3-dev
# work around LP: #1878225 as fallback
- name: Preparing autopkgtest-build-lxd
run: |
@@ -64,4 +69,5 @@ jobs:
run: |
# using --setup-commands temporarily to install:
# cmocka/pytest/rich/ethtool until they become proper test-deps
- sudo autopkgtest -U debian/artifacts/*.deb network-manager --apt-pocket=proposed=src:network-manager -- lxd autopkgtest/ubuntu/mantic/amd64 || test $? -eq 2 # allow for skipped tests (exit code = 2)
+ sudo autopkgtest -U debian/artifacts/*.deb \
+ network-manager --apt-pocket=proposed=src:network-manager -- lxd autopkgtest/ubuntu/mantic/amd64 || test $? -eq 2 # allow for skipped tests (exit code = 2)
diff --git a/.github/workflows/spread.yml b/.github/workflows/spread.yml
index b5eb87ab3..c1593f5c7 100644
--- a/.github/workflows/spread.yml
+++ b/.github/workflows/spread.yml
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: canonical/setup-lxd@v0.1.1
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Install spread
run: |
go install github.com/snapcore/spread/cmd/spread@latest
diff --git a/Makefile b/Makefile
index c2c6b742c..678e7c3a2 100644
--- a/Makefile
+++ b/Makefile
@@ -26,8 +26,10 @@ clean:
rm -rf _build
rm -rf _build-cov
rm -rf _leakcheckbuild
+ rm -rf _cleanbuild
rm -rf tmproot
rm -f python-cffi/netplan/_netplan_cffi.*
+ rm -f tools/keyfile_to_yaml
dist: clean _build
tar --exclude="_build" --exclude=".git" --exclude="debian" --exclude=".vscode" -cvJf ../netplan-$(VER).tar.xz .
diff --git a/TODO b/TODO
index de190e465..1416e40d5 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,5 @@
- improve IPv6 RA handling
-- support tunnel device types
-
- support ethtool/sysctl knobs (TSO, LRO, txqueuelen)
- inspecting current network config via "netplan show $interface" for a
@@ -11,10 +9,6 @@
- netplan diff system: compare generated config with current ip addr output
- netplan diff backend: compare generated config with current config for backend
-- support other devices types from networkd/NetworkManager:
- - infiniband
- - veth
-
- better handle VLAN Q-in-Q (mostly generation tweaks + patching backends)
- support device aliases (eth0 + eth0.1; add eth0 to multiple bridges)
@@ -26,22 +20,14 @@
- better parsing/validation for time-based values (ie. bond, bridge params)
-- openvswitch integration
-
-- wpa enterprise support
-
- better parsing/validation for all schema
-- improve exit codes / behavior on error
-
- integrate 'netplan try' in tmux/screen
- add automated integration tests for WPA Enterprise / 802.1x that can run self-contained
# After soname bump (ABI break)
-- get rid of abi_compat.c
-
- change route->scope to ENUM
- move tunnel_ttl into tunnel struct
diff --git a/abi-compat/jammy_0.107.xml b/abi-compat/jammy_0.107.xml
index f5c1b4092..a34616816 100644
--- a/abi-compat/jammy_0.107.xml
+++ b/abi-compat/jammy_0.107.xml
@@ -10,54 +10,38 @@
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
@@ -65,17 +49,15 @@
-
-
-
+
-
+
@@ -86,8 +68,6 @@
-
-
@@ -116,68 +96,292 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -195,77 +399,106 @@
-
-
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
@@ -283,1011 +516,878 @@
-
-
-
+
+
+
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
-
+
+
+
+
-
+
+
+
+
-
+
-
+
-
+
+
+
+
-
+
-
-
-
-
+
-
+
+
+
+
-
+
-
+
-
+
+
+
+
-
+
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
-
-
+
+
-
+
-
-
-
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
-
-
-
-
+
-
-
-
-
+
-
+
-
-
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
-
-
+
+
+
@@ -1295,895 +1395,293 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
-
-
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
-
-
+
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
+
+
+
-
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
+
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
-
-
+
+
-
+
-
+
-
+
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
-
-
+
-
-
-
-
+
+
+
+
@@ -2203,1081 +1701,1208 @@
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
@@ -3288,147 +2913,350 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
+
+
@@ -3452,92 +3280,92 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
@@ -3563,699 +3391,765 @@
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
-
+
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
+
+
+
-
-
-
+
+
+
@@ -4267,382 +4161,395 @@
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -4662,9 +4569,9 @@
-
-
-
+
+
+
@@ -4681,58 +4588,53 @@
-
-
-
+
+
+
-
+
-
+
-
-
-
-
-
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
diff --git a/abi-compat/suppressions.abignore b/abi-compat/suppressions.abignore
index d248137fb..c529f1834 100644
--- a/abi-compat/suppressions.abignore
+++ b/abi-compat/suppressions.abignore
@@ -3,7 +3,3 @@
#
# Documentation about the syntax can be found here:
# https://sourceware.org/libabigail/manual/libabigail-concepts.html#suppression-specifications
-
-[suppress_variable]
- name = global_state
- type_name = NetplanState
diff --git a/abicompat.lds b/abicompat.lds
deleted file mode 100644
index c91c632e7..000000000
--- a/abicompat.lds
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTIONS
-{
- .data.abi_compat : {
- netdefs = global_state + SIZEOF(netdefs_offset) - 8;
- netdefs_ordered = global_state + SIZEOF(netdefs_ordered_offset) - 8;
- ovs_settings_global = global_state + SIZEOF(ovs_settings_offset) - 8;
- global_backend = global_state + SIZEOF(global_backend_offset) - 8;
- }
-}
-INSERT AFTER .data;
diff --git a/include/netplan.h b/include/netplan.h
index 652561ebc..b0e50a5dd 100644
--- a/include/netplan.h
+++ b/include/netplan.h
@@ -139,11 +139,3 @@ netplan_netdef_get_dhcp6(const NetplanNetDefinition* netdef);
NETPLAN_PUBLIC ssize_t
netplan_netdef_get_macaddress(const NetplanNetDefinition* netdef, char* out_buffer, size_t out_buffer_size);
-
-/********** Old API below this ***********/
-
-NETPLAN_DEPRECATED NETPLAN_PUBLIC const char *
-netplan_netdef_get_filename(const NetplanNetDefinition* netdef);
-
-NETPLAN_PUBLIC void
-write_netplan_conf(const NetplanNetDefinition* def, const char* rootdir);
diff --git a/include/parse-nm.h b/include/parse-nm.h
index 311fc2389..a7356dfb0 100644
--- a/include/parse-nm.h
+++ b/include/parse-nm.h
@@ -30,8 +30,3 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, NetplanErr
//TODO: needs to be implemented
//NETPLAN_PUBLIC gboolean
//netplan_parser_load_keyfile_from_fd(NetplanParser* npp, int input_fd, NetplanError** error);
-
-/********** Old API below this ***********/
-
-NETPLAN_PUBLIC gboolean
-netplan_parse_keyfile(const char* filename, GError** error);
diff --git a/include/parse.h b/include/parse.h
index 41afb63e8..3d294b4c9 100644
--- a/include/parse.h
+++ b/include/parse.h
@@ -60,16 +60,3 @@ NETPLAN_PUBLIC gboolean
netplan_parser_load_nullable_overrides(
NetplanParser* npp, int input_fd, const char* constraint, NetplanError** error);
-/********** Old API below this ***********/
-
-NETPLAN_PUBLIC gboolean
-netplan_parse_yaml(const char* filename, GError** error);
-
-NETPLAN_PUBLIC GHashTable*
-netplan_finish_parse(GError** error);
-
-NETPLAN_PUBLIC guint
-netplan_clear_netdefs();
-
-NETPLAN_PUBLIC NetplanBackend
-netplan_get_global_backend();
diff --git a/include/types.h b/include/types.h
index 6f952c483..cbadcfdf6 100644
--- a/include/types.h
+++ b/include/types.h
@@ -23,7 +23,6 @@
#define NETPLAN_PUBLIC __attribute__ ((visibility("default")))
#define NETPLAN_INTERNAL __attribute__ ((visibility("default")))
-#define NETPLAN_ABI __attribute__ ((visibility("default")))
#define NETPLAN_DEPRECATED __attribute__ ((deprecated))
diff --git a/include/util.h b/include/util.h
index 1bd8b650d..b7b4a2fa7 100644
--- a/include/util.h
+++ b/include/util.h
@@ -74,17 +74,3 @@ netplan_util_create_yaml_patch(const char* conf_obj_path, const char* obj_payloa
NETPLAN_PUBLIC gboolean
netplan_util_dump_yaml_subtree(const char* prefix, int input_fd, int output_fd, NetplanError** error);
-
-/********** Old API below this ***********/
-
-/**
- * \deprecated Use `netplan_netdef_get_filepath()` instead.
- */
-NETPLAN_DEPRECATED NETPLAN_PUBLIC gchar*
-netplan_get_filename_by_id(const char* netdef_id, const char* rootdir);
-
-/**
- * \deprecated Use `netplan_get_id_from_nm_filepath()` instead.
- */
-NETPLAN_DEPRECATED NETPLAN_PUBLIC gchar*
-netplan_get_id_from_nm_filename(const char* filename, const char* ssid);
diff --git a/rpm/netplan.spec b/rpm/netplan.spec
index 877bdf291..8c6ed7c08 100644
--- a/rpm/netplan.spec
+++ b/rpm/netplan.spec
@@ -217,11 +217,6 @@ sed -e "s/werror=true/werror=false/g" -i meson.build
%install
%meson_install
-# Remove useless "compat" symlink and path
-rm -f %{buildroot}/lib/netplan/generate
-rmdir %{buildroot}/lib/netplan
-rmdir %{buildroot}/lib
-
# Remove superfluous __pycache__
rm -rf %{buildroot}/usr/lib/python3.11/site-packages/netplan/__pycache__
diff --git a/spread.yaml b/spread.yaml
index 60f154828..50afcc59d 100644
--- a/spread.yaml
+++ b/spread.yaml
@@ -23,15 +23,14 @@ prepare: |
# FIXME: having the debian packging available would allow "apt
# build-dep -y ./" would make this easier :)
apt update -qq
- apt install -y build-essential meson pkg-config libyaml-dev \
- libglib2.0-dev uuid-dev python3 libsystemd-dev pandoc python3-pytest \
- python3-coverage libcmocka-dev python3-rich python3-cffi libpython3-dev
+ apt install -y ubuntu-dev-tools devscripts equivs
+ pull-lp-source netplan.io
+ sed -i 's| openvswitch-switch|# DELETED: openvswitch-switch|' netplan.io-*/debian/control
+ mk-build-deps -i -r -B -s sudo -t "apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends" netplan.io-*/debian/control
# install, a bit ugly but this is a container (did I mention the packaging?)
meson setup build --prefix=/usr
meson compile -C build
- # FIXME: enable, this crashes right now with:
- # https://paste.ubuntu.com/p/qRnJvjyddN/
- #meson test -C build --verbose
+ #meson test -C build --verbose, cannot run OVS test in container
rm -rf /usr/share/netplan/netplan # clear (old) system installation
meson install -C build --destdir=/
# set some defaults
diff --git a/src/abi_compat.c b/src/abi_compat.c
deleted file mode 100644
index 10435aaf5..000000000
--- a/src/abi_compat.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2021 Canonical, Ltd.
- * Author: Simon Chopin
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-/*
- * The whole point of this file is to export the former ABI as simple wrappers
- * around the newer API. Most functions should thus be relatively short, the meat
- * of things being in the newer API implementation.
- */
-
-#include "netplan.h"
-#include "types-internal.h"
-#include "util-internal.h"
-#include "parse-nm.h"
-#include "parse-globals.h"
-#include "names.h"
-#include "networkd.h"
-#include "nm.h"
-#include "sriov.h"
-#include "openvswitch.h"
-#include "util.h"
-
-#include
-#include
-#include
-#include
-#include
-
-/* These arrays are not useful per-say, but allow us to export the various
- * struct offsets of the netplan_state members to the linker, which can use
- * them in a linker script to create symbols pointing to the internal data
- * members of the global_state global object.
- */
-
-/* The +8 is to prevent the compiler removing the array if the array is empty,
- * i.e. the data member is the first in the struct definition.
- */
-__attribute__((used)) __attribute__((section("netdefs_offset")))
-char _netdefs_off[8+offsetof(struct netplan_state, netdefs)] = {};
-
-__attribute__((used)) __attribute__((section("netdefs_ordered_offset")))
-char _netdefs_ordered_off[8+offsetof(struct netplan_state, netdefs_ordered)] = {};
-
-__attribute__((used)) __attribute__((section("ovs_settings_offset")))
-char _ovs_settings_global_off[8+offsetof(struct netplan_state, ovs_settings)] = {};
-
-__attribute__((used)) __attribute__((section("global_backend_offset")))
-char _global_backend_off[8+offsetof(struct netplan_state, backend)] = {};
-
-NETPLAN_ABI
-NetplanState global_state = {};
-
-// LCOV_EXCL_START
-NetplanBackend
-netplan_get_global_backend()
-{
- return netplan_state_get_backend(&global_state);
-}
-// LCOV_EXCL_STOP
-
-/**
- * Clear NetplanNetDefinition hashtable
- */
-// LCOV_EXCL_START
-guint
-netplan_clear_netdefs()
-{
- guint n = netplan_state_get_netdefs_size(&global_state);
- netplan_state_reset(&global_state);
- netplan_parser_reset(&global_parser);
- return n;
-}
-// LCOV_EXCL_STOP
-
-gboolean
-netplan_parse_yaml(const char* filename, GError** error)
-{
- return netplan_parser_load_yaml(&global_parser, filename, error);
-}
-
-/**
- * Post-processing after parsing all config files
- */
-GHashTable *
-netplan_finish_parse(GError** error)
-{
- if (netplan_state_import_parser_results(&global_state, &global_parser, error))
- return global_state.netdefs;
- return NULL; // LCOV_EXCL_LINE
-}
-
-/**
- * Generate the Netplan YAML configuration for the selected netdef
- * @def: NetplanNetDefinition (as pointer), the data to be serialized
- * @rootdir: If not %NULL, generate configuration in this root directory
- * (useful for testing).
- */
-void
-write_netplan_conf(const NetplanNetDefinition* def, const char* rootdir)
-{
- netplan_netdef_write_yaml(&global_state, def, rootdir, NULL);
-}
-
-/**
- * Generate the Netplan YAML configuration for all currently parsed netdefs
- * @file_hint: Name hint for the generated output YAML file
- * @rootdir: If not %NULL, generate configuration in this root directory
- * (useful for testing).
- */
-NETPLAN_ABI void
-write_netplan_conf_full(const char* file_hint, const char* rootdir)
-{
- g_autofree gchar *path = NULL;
- int fd = -1;
- netplan_finish_parse(NULL);
- if (!netplan_state_has_nondefault_globals(&global_state) &&
- !netplan_state_get_netdefs_size(&global_state))
- return;
- path = g_build_path(G_DIR_SEPARATOR_S, rootdir ?: G_DIR_SEPARATOR_S, "etc", "netplan", file_hint, NULL);
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (fd >= 0) {
- netplan_state_dump_yaml(&global_state, fd, NULL);
- close(fd);
- } else
- g_warning("write_netplan_conf_full: failed to open %s.", path); // LCOV_EXCL_LINE
-
-}
-
-NETPLAN_PUBLIC gboolean
-netplan_parse_keyfile(const char* filename, GError** error)
-{
- return netplan_parser_load_keyfile(&global_parser, filename, error);
-}
-
-// LCOV_EXCL_START
-void process_input_file(const char *f)
-{
- GError* error = NULL;
-
- g_debug("Processing input file %s..", f);
- if (!netplan_parser_load_yaml(&global_parser, f, &error)) {
- g_fprintf(stderr, "%s\n", error->message);
- exit(1);
- }
-}
-
-gboolean
-process_yaml_hierarchy(const char* rootdir)
-{
- GError* error = NULL;
- if (!netplan_parser_load_yaml_hierarchy(&global_parser, rootdir, &error)) {
- g_fprintf(stderr, "%s\n", error->message);
- exit(1);
- }
- return TRUE;
-}
-// LCOV_EXCL_STOP
-
-/**
- * Helper function for testing only
- */
-NETPLAN_INTERNAL void
-_write_netplan_conf(const char* netdef_id, const char* rootdir)
-{
- GHashTable* ht = NULL;
- const NetplanNetDefinition* def = NULL;
- ht = netplan_finish_parse(NULL);
- def = g_hash_table_lookup(ht, netdef_id);
- if (def)
- write_netplan_conf(def, rootdir);
- else
- g_warning("_write_netplan_conf: netdef_id (%s) not found.", netdef_id); // LCOV_EXCL_LINE
-}
-
-// LCOV_EXCL_START
-/**
- * Get the filename from which the given netdef has been parsed.
- * @rootdir: ID of the netdef to be looked up
- * @rootdir: parse files from this root directory
- */
-gchar*
-netplan_get_filename_by_id(const char* netdef_id, const char* rootdir)
-{
- NetplanParser* npp = netplan_parser_new();
- NetplanState* np_state = netplan_state_new();
- char *filepath = NULL;
- GError* error = NULL;
-
- if (!netplan_parser_load_yaml_hierarchy(npp, rootdir, &error) ||
- !netplan_state_import_parser_results(np_state, npp, &error)) {
- g_fprintf(stderr, "%s\n", error->message);
- netplan_parser_clear(&npp);
- netplan_state_clear(&np_state);
- return NULL;
- }
- netplan_parser_clear(&npp);
-
- NetplanNetDefinition* netdef = netplan_state_get_netdef(np_state, netdef_id);
- if (netdef)
- filepath = g_strdup(netdef->filepath);
- netplan_state_clear(&np_state);
- return filepath;
-}
-
-NETPLAN_INTERNAL struct netdef_pertype_iter*
-_netplan_state_new_netdef_pertype_iter(NetplanState* np_state, const char* devtype);
-
-NETPLAN_INTERNAL struct netdef_pertype_iter*
-_netplan_iter_defs_per_devtype_init(const char *devtype)
-{
- return _netplan_state_new_netdef_pertype_iter(&global_state, devtype);
-}
-
-NETPLAN_INTERNAL const char*
-_netplan_netdef_id(NetplanNetDefinition* netdef)
-{
- return netdef->id;
-}
-
-NETPLAN_ABI const char *
-netplan_netdef_get_filename(const NetplanNetDefinition* netdef)
-{
- g_assert(netdef);
- return netdef->filepath;
-}
-
-/*
- * Deprecated, use _netplan_netdef_get_embedded_switch_mode instead
- */
-NETPLAN_DEPRECATED NETPLAN_INTERNAL const char*
-netplan_netdef_get_embedded_switch_mode(const NetplanNetDefinition* netdef)
-{
- g_assert(netdef);
- return netdef->embedded_switch_mode;
-}
-
-/**
- * Extract the netplan netdef ID from a NetworkManager connection profile (keyfile),
- * generated by netplan. Used by the NetworkManager YAML backend.
- *
- * Note: Use netplan_get_id_from_nm_filepath instead.
- */
-gchar*
-netplan_get_id_from_nm_filename(const char* filename, const char* ssid)
-{
- size_t out_buf_size = 0;
- ssize_t ret = 0;
- g_autofree char* out_buffer = NULL;
-
- out_buf_size = strlen(filename);
- out_buffer = calloc(out_buf_size, 1);
-
- ret = netplan_get_id_from_nm_filepath(filename, ssid, out_buffer, out_buf_size);
-
- if (ret <= 0)
- return NULL;
-
- return g_strndup(out_buffer, ret);
-}
-// LCOV_EXCL_STOP
diff --git a/src/meson.build b/src/meson.build
index 1636fbc54..9e851b284 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,4 @@
sources = files(
- 'abi_compat.c',
'error.c',
'names.c',
'netplan.c',
@@ -13,13 +12,10 @@ sources = files(
'util.c',
'validation.c')
-linker_script = meson.project_source_root() / 'abicompat.lds'
libnetplan = library(
'netplan',
sources,
gnu_symbol_visibility: 'hidden',
- link_args: ['-T', linker_script],
- link_depends: linker_script,
dependencies: [glib, gio, yaml, uuid],
include_directories: inc,
soversion: '0.0',
@@ -37,8 +33,3 @@ executable(
meson.add_install_script(meson_make_symlink,
join_paths(get_option('prefix'), libexec_netplan, 'generate'),
join_paths(systemd_generator_dir, 'netplan'))
-# FIXME: Drop legacy symlink after 0.107 is released:
-# It's only around for legacy reasons, see netplan/cli/utils.py: get_generator_path()
-meson.add_install_script(meson_make_symlink,
- join_paths(get_option('prefix'), libexec_netplan, 'generate'),
- join_paths('/', 'lib', 'netplan', 'generate'))
diff --git a/src/names.c b/src/names.c
index 387f6d0d0..69ac0ffc3 100644
--- a/src/names.c
+++ b/src/names.c
@@ -152,11 +152,3 @@ NAME_FUNCTION_FLAGS(vxlan_extension);
}
ENUM_FUNCTION(def_type, NetplanDefType);
-
-/* ABI compatibility definitions */
-
-NETPLAN_ABI const char*
-tunnel_mode_to_string(NetplanTunnelMode val) __attribute__ ((alias ("netplan_tunnel_mode_name")));
-
-NETPLAN_ABI extern const char*
-netplan_backend_to_name __attribute__((alias("netplan_backend_to_str")));
diff --git a/src/parse-globals.h b/src/parse-globals.h
index 2065d747a..93492624e 100644
--- a/src/parse-globals.h
+++ b/src/parse-globals.h
@@ -38,6 +38,3 @@ ovs_settings_global;
extern NetplanBackend
global_backend;
-
-extern NetplanParser
-global_parser;
diff --git a/src/parse.c b/src/parse.c
index d70b564aa..8305906d2 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -55,10 +55,6 @@
dst = g_strdup(src); \
} }
-extern NetplanState global_state;
-
-NetplanParser global_parser = {0};
-
static gboolean
insert_kv_into_hash(void *key, void *value, void *hash);
@@ -1214,7 +1210,7 @@ handle_match(NetplanParser* npp, yaml_node_t* node, const char* key_prefix, __un
return process_mapping(npp, node, key_prefix, match_handlers, NULL, error);
}
-NETPLAN_ABI struct NetplanWifiWowlanType
+struct NetplanWifiWowlanType
NETPLAN_WIFI_WOWLAN_TYPES[] = {
{"default", NETPLAN_WIFI_WOWLAN_DEFAULT},
{"any", NETPLAN_WIFI_WOWLAN_ANY},
@@ -1680,7 +1676,7 @@ handle_link_local(NetplanParser* npp, yaml_node_t* node, __unused const void* _,
return TRUE;
}
-NETPLAN_ABI struct NetplanOptionalAddressType
+struct NetplanOptionalAddressType
NETPLAN_OPTIONAL_ADDRESS_TYPES[] = {
{"ipv4-ll", NETPLAN_OPTIONAL_IPV4_LL},
{"ipv6-ra", NETPLAN_OPTIONAL_IPV6_RA},
diff --git a/src/types.c b/src/types.c
index b885e6cf5..f066eb3a2 100644
--- a/src/types.c
+++ b/src/types.c
@@ -516,9 +516,6 @@ netplan_netdef_get_vlan_link(const NetplanNetDefinition* netdef)
return netdef->vlan_link;
}
-__attribute((alias("netplan_netdef_get_vlan_link"))) NETPLAN_INTERNAL NetplanNetDefinition*
-_netplan_netdef_get_vlan_link(const NetplanNetDefinition* netdef);
-
NetplanNetDefinition*
netplan_netdef_get_sriov_link(const NetplanNetDefinition* netdef)
{
@@ -526,9 +523,6 @@ netplan_netdef_get_sriov_link(const NetplanNetDefinition* netdef)
return netdef->sriov_link;
}
-__attribute((alias("netplan_netdef_get_sriov_link"))) NETPLAN_INTERNAL NetplanNetDefinition*
-_netplan_netdef_get_sriov_link(const NetplanNetDefinition* netdef);
-
NetplanNetDefinition*
netplan_netdef_get_bridge_link(const NetplanNetDefinition* netdef)
{
@@ -564,16 +558,13 @@ _netplan_netdef_get_embedded_switch_mode(const NetplanNetDefinition* netdef, cha
return netplan_copy_string(netdef->embedded_switch_mode, out_buffer, out_buf_size);
}
-gboolean
-_netplan_netdef_get_delay_vf_rebind(const NetplanNetDefinition* netdef)
+NETPLAN_INTERNAL gboolean
+netplan_netdef_get_delay_virtual_functions_rebind(const NetplanNetDefinition* netdef)
{
g_assert(netdef);
return netdef->sriov_delay_virtual_functions_rebind;
}
-__attribute((alias("_netplan_netdef_get_delay_vf_rebind"))) NETPLAN_INTERNAL gboolean
-netplan_netdef_get_delay_virtual_functions_rebind(const NetplanNetDefinition* netdef);
-
gboolean
netplan_netdef_has_match(const NetplanNetDefinition* netdef)
{
diff --git a/src/util-internal.h b/src/util-internal.h
index fe41c776e..4ecdceccd 100644
--- a/src/util-internal.h
+++ b/src/util-internal.h
@@ -34,7 +34,7 @@ wifi_frequency_24;
extern GHashTable*
wifi_frequency_5;
-NETPLAN_ABI void
+NETPLAN_INTERNAL void
safe_mkdir_p_dir(const char* file_path);
NETPLAN_INTERNAL void
@@ -46,19 +46,19 @@ unlink_glob(const char* rootdir, const char* _glob);
NETPLAN_INTERNAL int
find_yaml_glob(const char* rootdir, glob_t* out_glob);
-NETPLAN_ABI const char*
+const char*
get_global_network(int ip_family);
-NETPLAN_ABI const char*
+const char*
get_unspecified_address(int ip_family);
-NETPLAN_ABI int
+int
wifi_get_freq24(int channel);
-NETPLAN_ABI int
+int
wifi_get_freq5(int channel);
-NETPLAN_ABI gchar*
+gchar*
systemd_escape(char* string);
#define OPENVSWITCH_OVS_VSCTL "/usr/bin/ovs-vsctl"
@@ -78,12 +78,6 @@ netplan_netdef_new(NetplanParser* npp, const char* id, NetplanDefType type, Netp
const char *
netplan_parser_get_filename(NetplanParser* npp);
-NETPLAN_INTERNAL void
-process_input_file(const char* f);
-
-NETPLAN_INTERNAL gboolean
-process_yaml_hierarchy(const char* rootdir);
-
gboolean
has_openvswitch(const NetplanOVSSettings* ovs, NetplanBackend backend, GHashTable *ovs_ports);
diff --git a/src/util.c b/src/util.c
index cbd5ac203..ab2e644fd 100644
--- a/src/util.c
+++ b/src/util.c
@@ -35,10 +35,10 @@
#include "names.h"
#include "yaml-helpers.h"
-NETPLAN_ABI GHashTable*
+GHashTable*
wifi_frequency_24;
-NETPLAN_ABI GHashTable*
+GHashTable*
wifi_frequency_5;
const gchar* FALLBACK_FILENAME = "70-netplan-set.yaml";
@@ -884,7 +884,6 @@ _netplan_state_new_netdef_pertype_iter(NetplanState* np_state, const char* def_t
return iter;
}
-
NetplanNetDefinition*
_netplan_netdef_pertype_iter_next(struct netdef_pertype_iter* it)
{
@@ -909,12 +908,6 @@ _netplan_netdef_pertype_iter_free(struct netdef_pertype_iter* it)
g_free(it);
}
-__attribute((alias("_netplan_netdef_pertype_iter_next"))) NETPLAN_ABI NetplanNetDefinition*
-_netplan_iter_defs_per_devtype_next(struct netdef_pertype_iter* it);
-
-__attribute((alias("_netplan_netdef_pertype_iter_free"))) NETPLAN_ABI void
-_netplan_iter_defs_per_devtype_free(struct netdef_pertype_iter* it);
-
gboolean
has_openvswitch(const NetplanOVSSettings* ovs, NetplanBackend backend, GHashTable *ovs_ports)
{
diff --git a/src/validation.h b/src/validation.h
index 1259eb2b9..2accb0a08 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -27,7 +27,7 @@ gboolean is_ip6_address(const char* address);
gboolean is_hostname(const char* hostname);
gboolean validate_ovs_target(gboolean host_first, gchar* s);
-NETPLAN_ABI gboolean
+gboolean
is_wireguard_key(const char* hostname);
gboolean
diff --git a/tests/ctests/meson.build b/tests/ctests/meson.build
index 8a41e9a30..fa949d61f 100644
--- a/tests/ctests/meson.build
+++ b/tests/ctests/meson.build
@@ -3,7 +3,6 @@ tests = {
'test_netplan_state': false,
'test_netplan_error': false,
'test_netplan_misc': false,
- 'test_netplan_deprecated': false,
'test_netplan_validation': false,
'test_netplan_keyfile': false,
'test_netplan_nm': false,
diff --git a/tests/ctests/test_netplan_deprecated.c b/tests/ctests/test_netplan_deprecated.c
deleted file mode 100644
index 1d87e48a6..000000000
--- a/tests/ctests/test_netplan_deprecated.c
+++ /dev/null
@@ -1,84 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include
-
-#include "netplan.h"
-#include "parse.h"
-#include "types-internal.h"
-#include "types.h"
-
-#include "error.c"
-#include "names.c"
-#include "validation.c"
-#include "types.c"
-#include "util.c"
-#include "parse.c"
-#include "netplan.c"
-
-// LCOV_EXCL_START
-gboolean
-netplan_parser_load_keyfile(__unused NetplanParser* npp, __unused const char* filename, __unused NetplanError** error)
-{
- return 1; //
-}
-// LCOV_EXCL_STOP
-
-#include "abi_compat.c"
-
-#include "test_utils.h"
-
-void
-test_netplan_get_id_from_nm_filename_no_ssid(__unused void **state)
-{
- const char* filename = "/some/rootdir/run/NetworkManager/system-connections/netplan-some-id.nmconnection";
- char* id = netplan_get_id_from_nm_filename(filename, NULL);
- assert_string_equal(id, "some-id");
- g_free(id);
-}
-
-void
-test_netplan_get_id_from_nm_filename_with_ssid(__unused void **state)
-{
- const char* filename = "/some/rootdir/run/NetworkManager/system-connections/netplan-some-id-SOME-SSID.nmconnection";
- char* id = netplan_get_id_from_nm_filename(filename, "SOME-SSID");
- assert_string_equal(id, "some-id");
- g_free(id);
-}
-
-void
-test_netplan_get_id_from_nm_filename_filename_is_malformed(__unused void **state)
-{
- const char* filename = "INVALID/netplan-some-id.nmconnection";
- char* id = netplan_get_id_from_nm_filename(filename, NULL);
- assert_null(id);
-}
-
-
-int
-setup(__unused void** state)
-{
- return 0;
-}
-
-int
-tear_down(__unused void** state)
-{
- return 0;
-}
-
-int
-main()
-{
-
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_netplan_get_id_from_nm_filename_no_ssid),
- cmocka_unit_test(test_netplan_get_id_from_nm_filename_with_ssid),
- cmocka_unit_test(test_netplan_get_id_from_nm_filename_filename_is_malformed),
- };
-
- return cmocka_run_group_tests(tests, setup, tear_down);
-
-}
diff --git a/tests/ctests/test_netplan_misc.c b/tests/ctests/test_netplan_misc.c
index 35bf4f85b..901e8a0a6 100644
--- a/tests/ctests/test_netplan_misc.c
+++ b/tests/ctests/test_netplan_misc.c
@@ -47,6 +47,18 @@ test_netplan_get_id_from_nm_filepath_no_ssid(__unused void **state)
assert_int_equal(bytes_copied, 8); // size of some-id + null byte
}
+void
+test_netplan_get_id_from_nm_filepath_no_nmconnection(__unused void **state)
+{
+
+ const char* filename = "/some/rootdir/run/NetworkManager/system-connections/netplan-some-id";
+ char id[16];
+
+ ssize_t bytes_copied = netplan_get_id_from_nm_filepath(filename, NULL, id, sizeof(id));
+
+ assert_int_equal(bytes_copied, 0);
+}
+
void
test_netplan_get_id_from_nm_filepath_with_ssid(__unused void **state)
{
@@ -177,6 +189,107 @@ test_netplan_netdef_get_output_filename_invalid_backend(__unused void** state)
assert_int_equal(ret, 0);
}
+void
+test_netplan_netdef_write_yaml(__unused void** state)
+{
+ const char* yaml =
+ "network:\n"
+ " version: 2\n"
+ " ethernets:\n"
+ " eth0:\n"
+ " dhcp4: true";
+
+ NetplanState* np_state = load_string_to_netplan_state(yaml);
+ NetplanNetDefinition* interface = netplan_state_get_netdef(np_state, "eth0");
+
+ char template[] = "/tmp/netplan.XXXXXX";
+ // no need to free() rootdir, as it will modify the template[] buffer
+ char *rootdir = mkdtemp(template);
+ char etc[24] = {0};
+ char etc_netplan[32] = {0};
+ snprintf(etc, 24, "%s/etc", rootdir);
+ snprintf(etc_netplan, 32, "%s/netplan", etc);
+ mkdir(etc, 0770);
+ mkdir(etc_netplan, 0770);
+
+ /* Check API call */
+ NetplanError* err = NULL;
+ assert_true(netplan_netdef_write_yaml(np_state, interface, rootdir, &err));
+ assert_true(err == NULL);
+
+ /* Check file exists */
+ struct stat st = {0};
+ char output_yaml[53] = {0};
+ snprintf(output_yaml, 53, "%s/10-netplan-eth0.yaml", etc_netplan);
+ assert_true(stat(output_yaml, &st) == 0);
+
+ /* Check file contents */
+ FILE *fd = fopen(output_yaml, "r");
+ char file_buffer[600] = {0};
+ assert_true(fread(file_buffer, 1, strlen(yaml), fd) > 0);
+ assert_string_equal(yaml, file_buffer);
+
+ /* Cleanup */
+ netplan_state_clear(&np_state);
+ fclose(fd);
+ remove(output_yaml);
+ rmdir(etc_netplan);
+ rmdir(etc);
+ rmdir(rootdir);
+}
+
+void
+test_netplan_netdef_write_yaml_90NM(__unused void** state)
+{
+ const char* yaml =
+ "network:\n"
+ " version: 2\n"
+ //" renderer: NetworkManager\n" //FIXME: renderer get's eaten by the API call...
+ " ethernets:\n"
+ " eth0:\n"
+ " dhcp4: true\n"
+ " networkmanager:\n"
+ " uuid: \"990548be-01ed-42d7-9f9f-cd4966b25c08\"";
+
+ NetplanState* np_state = load_string_to_netplan_state(yaml);
+ NetplanNetDefinition* interface = netplan_state_get_netdef(np_state, "eth0");
+
+ char template[] = "/tmp/netplan.XXXXXX";
+ // no need to free() rootdir, as it will modify the template[] buffer
+ char *rootdir = mkdtemp(template);
+ char etc[24] = {0};
+ char etc_netplan[32] = {0};
+ snprintf(etc, 24, "%s/etc", rootdir);
+ snprintf(etc_netplan, 32, "%s/netplan", etc);
+ mkdir(etc, 0770);
+ mkdir(etc_netplan, 0770);
+
+ /* Check API call */
+ NetplanError* err = NULL;
+ assert_true(netplan_netdef_write_yaml(np_state, interface, rootdir, &err));
+ assert_true(err == NULL);
+
+ /* Check file exists */
+ struct stat st = {0};
+ char output_yaml[80] = {0};
+ snprintf(output_yaml, 80, "%s/90-NM-990548be-01ed-42d7-9f9f-cd4966b25c08.yaml", etc_netplan);
+ assert_true(stat(output_yaml, &st) == 0);
+
+ /* Check file contents */
+ FILE *fd = fopen(output_yaml, "r");
+ char file_buffer[600] = {0};
+ assert_true(fread(file_buffer, 1, strlen(yaml), fd) > 0);
+ assert_string_equal(yaml, file_buffer);
+
+ /* Cleanup */
+ netplan_state_clear(&np_state);
+ fclose(fd);
+ remove(output_yaml);
+ rmdir(etc_netplan);
+ rmdir(etc);
+ rmdir(rootdir);
+}
+
void
test_util_is_route_present(__unused void** state)
{
@@ -367,6 +480,7 @@ main()
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_netplan_get_optional),
cmocka_unit_test(test_netplan_get_id_from_nm_filepath_no_ssid),
+ cmocka_unit_test(test_netplan_get_id_from_nm_filepath_no_nmconnection),
cmocka_unit_test(test_netplan_get_id_from_nm_filepath_with_ssid),
cmocka_unit_test(test_netplan_get_id_from_nm_filepath_buffer_is_too_small),
cmocka_unit_test(test_netplan_get_id_from_nm_filepath_buffer_is_the_exact_size),
@@ -376,6 +490,8 @@ main()
cmocka_unit_test(test_netplan_netdef_get_output_filename_networkd),
cmocka_unit_test(test_netplan_netdef_get_output_filename_buffer_is_too_small),
cmocka_unit_test(test_netplan_netdef_get_output_filename_invalid_backend),
+ cmocka_unit_test(test_netplan_netdef_write_yaml),
+ cmocka_unit_test(test_netplan_netdef_write_yaml_90NM),
cmocka_unit_test(test_util_is_route_present),
cmocka_unit_test(test_util_is_route_rule_present),
cmocka_unit_test(test_util_is_string_in_array),
diff --git a/tests/generator/base.py b/tests/generator/base.py
index b7bf4f96c..8f856657b 100644
--- a/tests/generator/base.py
+++ b/tests/generator/base.py
@@ -32,6 +32,9 @@
import yaml
import difflib
import re
+from io import StringIO
+
+import netplan
exe_generate = os.environ.get('NETPLAN_GENERATE_PATH',
os.path.join(os.path.dirname(os.path.dirname(
@@ -269,31 +272,33 @@ def validate_generated_yaml(self, yaml_input):
original (and normalized) input with the generated (and normalized)
output.
'''
- output = '_generated_test_output.yaml'
- output_path = os.path.join(self.confdir, output)
for input in yaml_input:
- lib.netplan_clear_netdefs() # clear previous netdefs
- lib.netplan_parse_yaml(input.encode(), None)
- lib.write_netplan_conf_full(output.encode(), self.workdir.name.encode())
+ parser = netplan.Parser()
+ parser.load_yaml(input)
+ state = netplan.State()
+ state.import_parser_results(parser)
+
+ # TODO: Allow handling of full hierarchy overrides,
+ # dealing only with the current element of 'yaml_input'.
+ # E.g. allow vlan.id & vlan.link to be defined in a base file.
+ # See test_routing.py:
+ # test_add_routes_to_different_tables_from_multiple_files
+ # test_add_duplicate_routes_from_multiple_files
- input_yaml = None
- output_yaml = None
+ # Read output of the YAML generator (if any)
+ output_fd = StringIO()
+ state._dump_yaml(output_fd)
+ output_yaml = yaml.safe_load(output_fd.getvalue())
# Read input YAML file, as defined by the self.generate('...') method
+ input_yaml = None
with open(input, 'r') as orig:
input_yaml = yaml.safe_load(orig.read())
# Consider 'network: {}' and 'network: {version: 2}' to be empty
if input_yaml is None or input_yaml == {'network': {}} or input_yaml == {'network': {'version': 2}}:
input_yaml = yaml.safe_load('')
- # Read output of the YAML generator (if any)
- if os.path.isfile(output_path):
- with open(output_path, 'r') as generated:
- output_yaml = yaml.safe_load(generated.read())
- else:
- output_yaml = yaml.safe_load('')
-
# Normalize input and output YAML
netplan_normalizer = NetplanV2Normalizer()
input_lines = netplan_normalizer.normalize_yaml(input_yaml)
@@ -312,11 +317,6 @@ def validate_generated_yaml(self, yaml_input):
print(line, flush=True)
self.fail('Re-generated YAML file does not match (adopt netplan.c YAML generator?)')
- # Cleanup the generated file and data structures
- lib.netplan_clear_netdefs()
- if os.path.isfile(output_path):
- os.remove(output_path)
-
def generate(self, yaml, expect_fail=False, extra_args=[], confs=None, skip_generated_yaml_validation=False):
'''Call generate with given YAML string as configuration
diff --git a/tests/generator/test_routing.py b/tests/generator/test_routing.py
index f3ed2b385..e726f40f0 100644
--- a/tests/generator/test_routing.py
+++ b/tests/generator/test_routing.py
@@ -1470,8 +1470,11 @@ def test_add_routes_to_different_tables_from_multiple_files(self):
link: eth0''',
'10-table1': '''network:
version: 2
+ ethernets: {eth0: {dhcp4: true}}
vlans:
vlan100:
+ id: 100
+ link: eth0
routing-policy:
- from: 10.0.0.1
table: 1001
@@ -1481,8 +1484,11 @@ def test_add_routes_to_different_tables_from_multiple_files(self):
table: 1001''',
'10-table2': '''network:
version: 2
+ ethernets: {eth0: {dhcp4: true}}
vlans:
vlan100:
+ id: 100
+ link: eth0
routing-policy:
- from: 10.0.0.2
table: 1002
@@ -1530,8 +1536,11 @@ def test_add_duplicate_routes_from_multiple_files(self):
link: eth0''',
'10-table1': '''network:
version: 2
+ ethernets: {eth0: {dhcp4: true}}
vlans:
vlan100:
+ id: 100
+ link: eth0
routing-policy:
- from: 10.0.0.1
table: 1001
@@ -1541,8 +1550,11 @@ def test_add_duplicate_routes_from_multiple_files(self):
table: 1001''',
'10-table2': '''network:
version: 2
+ ethernets: {eth0: {dhcp4: true}}
vlans:
vlan100:
+ id: 100
+ link: eth0
routing-policy:
- from: 10.0.0.2
table: 1002
diff --git a/tests/integration/regressions.py b/tests/integration/regressions.py
index 7d2bb43da..2976a44f8 100644
--- a/tests/integration/regressions.py
+++ b/tests/integration/regressions.py
@@ -21,7 +21,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-import json
import os
import sys
import signal
@@ -165,57 +164,4 @@ def test_try_accept_lp1959570(self):
self.assertIn('Configuration accepted.', out)
-class TestDbus(IntegrationTestsBase):
- # This test can be dropped when tests/integration/dbus.py is
- # integrated as an autopkgtest in the Debian package
- def test_dbus_config_get_lp1997467(self):
-
- NETPLAN_YAML = '''network:
- version: 2
- ethernets:
- %(nic)s:
- dhcp4: true
-'''
- BUSCTL_CONFIG = [
- 'busctl', '-j', 'call', '--system',
- 'io.netplan.Netplan', '/io/netplan/Netplan',
- 'io.netplan.Netplan', 'Config']
-
- BUSCTL_CONFIG_GET = [
- 'busctl', '-j', 'call', '--system',
- 'io.netplan.Netplan', 'PLACEHOLDER',
- 'io.netplan.Netplan.Config', 'Get']
-
- # Terminates netplan-dbus if it is running already
- cmd = ['ps', '-C', 'netplan-dbus', '-o', 'pid=']
- out = subprocess.run(cmd, capture_output=True, text=True)
- if out.returncode == 0:
- pid = out.stdout.strip()
- os.kill(int(pid), signal.SIGTERM)
-
- with open(self.config, 'w') as f:
- f.write(NETPLAN_YAML % {'nic': self.dev_e_client})
-
- out = subprocess.run(BUSCTL_CONFIG, capture_output=True, text=True)
- self.assertEqual(out.returncode, 0, msg=f"Busctl Config() failed with error: {out.stderr}")
-
- out_dict = json.loads(out.stdout)
- config_path = out_dict.get('data')[0]
- self.assertNotEqual(config_path, "", msg="Got an empty response from DBUS")
-
- # The path has the following format: /io/netplan/Netplan/config/WM6X01
- BUSCTL_CONFIG_GET[5] = config_path
-
- # Retrieving the config
- out = subprocess.run(BUSCTL_CONFIG_GET, capture_output=True, text=True)
- self.assertEqual(out.returncode, 0, msg=f"Busctl Get() failed with error: {out.stderr}")
-
- out_dict = json.loads(out.stdout)
- netplan_data = out_dict.get('data')[0]
-
- self.assertNotEqual(netplan_data, "", msg="Got an empty response from DBUS")
- self.assertEqual(netplan_data, NETPLAN_YAML % {'nic': self.dev_e_client},
- msg="The original YAML is different from the one returned by DBUS")
-
-
unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
diff --git a/tests/parser/test_keyfile.py b/tests/parser/test_keyfile.py
index 1351840c6..7c1aa6500 100644
--- a/tests/parser/test_keyfile.py
+++ b/tests/parser/test_keyfile.py
@@ -21,13 +21,14 @@
import ctypes
import ctypes.util
+import netplan
+
from .base import TestKeyfileBase
rootdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
exe_cli = os.path.join(rootdir, 'src', 'netplan.script')
lib = ctypes.CDLL(ctypes.util.find_library('netplan'))
-lib.netplan_get_id_from_nm_filename.restype = ctypes.c_char_p
UUID = 'ff9d6ebc-226d-4f82-a485-b7ff83b9607f'
@@ -362,28 +363,34 @@ def test_keyfile_dummy(self): # wokeignore:rule=dummy
name: "Test"
'''.format(UUID, UUID)})
- def _template_keyfile_type(self, nd_type, nm_type, supported=True):
+ def _template_keyfile_type(self, nd_type, nm_type):
self.maxDiff = None
+ extra = ''
file = os.path.join(self.workdir.name, 'tmp/some.keyfile')
os.makedirs(os.path.dirname(file))
with open(file, 'w') as f:
f.write('[connection]\ntype={}\nuuid={}'.format(nm_type, UUID))
- self.assertEqual(lib.netplan_clear_netdefs(), 0)
- lib.netplan_parse_keyfile(file.encode(), None)
- lib._write_netplan_conf('NM-{}'.format(UUID).encode(), self.workdir.name.encode())
- lib.netplan_clear_netdefs()
- self.assertTrue(os.path.isfile(os.path.join(self.confdir, '90-NM-{}.yaml'.format(UUID))))
- t = '\n passthrough:\n connection.type: "{}"'.format(nm_type) if not supported else ''
- match = '\n match: {}' if nd_type in ['ethernets', 'modems', 'wifis'] else ''
- with open(os.path.join(self.confdir, '90-NM-{}.yaml'.format(UUID)), 'r') as f:
+ if nm_type == 'ip-tunnel':
+ f.write('\n\n[ip-tunnel]\nmode=4\nremote=10.0.0.1')
+ extra = '\n mode: "isatap"\n remote: "10.0.0.1"'
+ if nd_type in ['ethernets', 'modems', 'wifis']:
+ extra = '\n match: {}'
+ parser = netplan.Parser()
+ state = netplan.State()
+ parser.load_keyfile(file)
+ state.import_parser_results(parser)
+ output_file = '90-NM-{}.yaml'.format(UUID)
+ state._write_yaml_file(output_file, self.workdir.name)
+ self.assertTrue(os.path.isfile(os.path.join(self.confdir, output_file)))
+ with open(os.path.join(self.confdir, output_file), 'r') as f:
self.assertEqual(f.read(), '''network:
version: 2
{}:
NM-{}:
renderer: NetworkManager{}
networkmanager:
- uuid: "{}"{}
-'''.format(nd_type, UUID, match, UUID, t))
+ uuid: "{}"
+'''.format(nd_type, UUID, extra, UUID))
def test_keyfile_ethernet(self):
self._template_keyfile_type('ethernets', 'ethernet')
@@ -401,7 +408,7 @@ def test_keyfile_type_bond(self):
self._template_keyfile_type('bonds', 'bond')
def test_keyfile_type_tunnel(self):
- self._template_keyfile_type('tunnels', 'ip-tunnel', False)
+ self._template_keyfile_type('tunnels', 'ip-tunnel')
def test_keyfile_type_wifi(self):
self.generate_from_keyfile('''[connection]
diff --git a/tests/test_libnetplan.py b/tests/test_libnetplan.py
index 6696cd2d4..e54375f8e 100644
--- a/tests/test_libnetplan.py
+++ b/tests/test_libnetplan.py
@@ -39,8 +39,6 @@
# We still need direct (ctypes) access to libnetplan.so to test certain cases
# that are not covered by the 'netplan' module bindings
lib = ctypes.CDLL(ctypes.util.find_library('netplan'))
-# Define some libnetplan.so ABI
-lib.netplan_get_id_from_nm_filename.restype = ctypes.c_char_p
rootdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
exe_cli = os.path.join(rootdir, 'src', 'netplan.script')
@@ -55,40 +53,15 @@ def setUp(self):
def tearDown(self):
shutil.rmtree(self.workdir.name)
- lib.netplan_clear_netdefs()
super().tearDown()
- def test_get_id_from_filename(self):
- out = lib.netplan_get_id_from_nm_filename(
- '/run/NetworkManager/system-connections/netplan-some-id.nmconnection'.encode(), None)
- self.assertEqual(out, b'some-id')
-
- def test_get_id_from_filename_rootdir(self):
- out = lib.netplan_get_id_from_nm_filename(
- '/some/rootdir/run/NetworkManager/system-connections/netplan-some-id.nmconnection'.encode(), None)
- self.assertEqual(out, b'some-id')
-
- def test_get_id_from_filename_wifi(self):
- out = lib.netplan_get_id_from_nm_filename(
- '/run/NetworkManager/system-connections/netplan-some-id-SOME-SSID.nmconnection'.encode(), 'SOME-SSID'.encode())
- self.assertEqual(out, b'some-id')
-
- def test_get_id_from_filename_wifi_invalid_suffix(self):
- out = lib.netplan_get_id_from_nm_filename(
- '/run/NetworkManager/system-connections/netplan-some-id-SOME-SSID'.encode(), 'SOME-SSID'.encode())
- self.assertEqual(out, None)
-
- def test_get_id_from_filename_invalid_prefix(self):
- out = lib.netplan_get_id_from_nm_filename('INVALID/netplan-some-id.nmconnection'.encode(), None)
- self.assertEqual(out, None)
-
def test_parse_keyfile_missing(self):
+ parser = netplan.Parser()
f = os.path.join(self.workdir.name, 'tmp/some.keyfile')
os.makedirs(os.path.dirname(f))
- with capture_stderr() as outf:
- self.assertFalse(lib.netplan_parse_keyfile(f.encode(), None))
- with open(outf.name, 'r') as f:
- self.assertIn('netplan: cannot load keyfile', f.read().strip())
+ with self.assertRaises(netplan.NetplanException) as ctx:
+ parser.load_keyfile(f)
+ self.assertIn('No such file or directory', str(ctx.exception))
def test_generate(self):
self.mock_netplan_cmd = MockCmd("netplan")
@@ -153,28 +126,6 @@ def test_delete_connection_invalid(self):
with open(outf.name, 'r') as f:
self.assertIn('Cannot parse input', f.read())
- def test_write_netplan_conf(self):
- netdef_id = 'some-netplan-id'
- orig = os.path.join(self.confdir, 'some-filename.yaml')
- generated = os.path.join(self.confdir, '10-netplan-{}.yaml'.format(netdef_id))
- with open(orig, 'w') as f:
- f.write('''network:
- version: 2
- ethernets:
- some-netplan-id:
- renderer: networkd
- match:
- name: "eth42"
-''')
- # Parse YAML and and re-write the specified netdef ID into a new file
- self.assertTrue(lib.netplan_parse_yaml(orig.encode(), None))
- lib._write_netplan_conf(netdef_id.encode(), self.workdir.name.encode())
- self.assertEqual(lib.netplan_clear_netdefs(), 1)
- self.assertTrue(os.path.isfile(generated))
- with open(orig, 'r') as f:
- with open(generated, 'r') as new:
- self.assertEqual(f.read(), new.read())
-
class TestNetdefIterator(TestBase):
def test_with_empty_netplan(self):
diff --git a/tools/run_asan.sh b/tools/run_asan.sh
index 73ed35e38..0b906fb04 100755
--- a/tools/run_asan.sh
+++ b/tools/run_asan.sh
@@ -35,16 +35,16 @@ do
# Set the renderer and check if the new file can be parsed with the new renderer
# We use the clean build because it will not fail if there's a memory leak
- LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" netplan set --root-dir ${BUILDDIR}/fakeroot --origin-hint ${filename/.yaml/} network.renderer=networkd
- if LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" netplan generate --root-dir ${BUILDDIR}/fakeroot > /dev/null 2>&1
+ PYTHONPATH=".:${CLEANBUILDDIR}/python-cffi" LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" src/netplan.script set --root-dir ${BUILDDIR}/fakeroot --origin-hint ${filename/.yaml/} network.renderer=networkd
+ if PYTHONPATH=".:${CLEANBUILDDIR}/python-cffi" LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" src/netplan.script generate --root-dir ${BUILDDIR}/fakeroot > /dev/null 2>&1
then
LD_LIBRARY_PATH="${BUILDDIR}/src" ./${BUILDDIR}/src/generate --root-dir ${BUILDDIR}/fakeroot
else
echo "File ${filename} can't be parsed with renderer = networkd"
fi
- LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" netplan set --root-dir ${BUILDDIR}/fakeroot --origin-hint ${filename/.yaml/} network.renderer=NetworkManager
- if LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" netplan generate --root-dir ${BUILDDIR}/fakeroot > /dev/null 2>&1
+ PYTHONPATH=".:${CLEANBUILDDIR}/python-cffi" LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" src/netplan.script set --root-dir ${BUILDDIR}/fakeroot --origin-hint ${filename/.yaml/} network.renderer=NetworkManager
+ if PYTHONPATH=".:${CLEANBUILDDIR}/python-cffi" LD_LIBRARY_PATH="${CLEANBUILDDIR}/src" src/netplan.script generate --root-dir ${BUILDDIR}/fakeroot > /dev/null 2>&1
then
LD_LIBRARY_PATH="${BUILDDIR}/src" ./${BUILDDIR}/src/generate --root-dir ${BUILDDIR}/fakeroot
for keyfile in $(find ${BUILDDIR}/fakeroot/run/NetworkManager/system-connections/ -type f)