Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ifupdown: T6038: Cleanup network config properly #75

Merged
merged 1 commit into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 1 addition & 31 deletions cloudinit/config/cc_vyos.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import re
import ipaddress
from pathlib import Path
from subprocess import run, DEVNULL
from subprocess import run
from uuid import uuid4
from cloudinit import log as logging
from cloudinit.ssh_util import AuthKeyLineParser
Expand Down Expand Up @@ -992,33 +992,6 @@ def set_config_hostname(config, hostname, fqdn):
logger.error("Failed to configure domain-name: {}".format(err))


# cleanup network interface config file added by cloud-init
def network_cleanup():
logger.debug("Cleaning up network configuration applied by Cloud-Init")
net_config_file = Path('/etc/network/interfaces.d/50-cloud-init')
if net_config_file.exists():
logger.debug(f"Configuration file {net_config_file} was found")
try:
# get a list of interfaces that need to be deconfigured
configured_ifaces = run(
['ifquery', '-l', '-X', 'lo', '-i', net_config_file],
capture_output=True).stdout.decode().splitlines()
if configured_ifaces:
for iface in configured_ifaces:
logger.debug(f"Deconfiguring interface: {iface}")
run(['ifdown', iface], stdout=DEVNULL)
# delete the file
net_config_file.unlink()
logger.debug(f"Configuration file {net_config_file} was removed")
except Exception as err:
logger.error(f"Failed to cleanup network configuration: {err}")

udev_rules_file = Path('/etc/udev/rules.d/70-persistent-net.rules')
if udev_rules_file.exists():
logger.debug(f"Configuration file {udev_rules_file} was removed")
udev_rules_file.unlink()


# main config handler
def handle(name, cfg, cloud, log, _args):
logger.debug("Cloud-init config: {}".format(cfg))
Expand Down Expand Up @@ -1182,6 +1155,3 @@ def handle(name, cfg, cloud, log, _args):
logger.debug("Configuration file saved: {}".format(cfg_file_name))
except Exception as e:
logger.error("Failed to write configs into file {}: {}".format(cfg_file_name, e))

# since we already have a config file, it is a time to clean up what Cloud-init may left
network_cleanup()
62 changes: 62 additions & 0 deletions cloudinit/config/cc_vyos_ifupdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright (C) 2024 VyOS Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# 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 <http://www.gnu.org/licenses/>.

# This module is used to cleanup ifupdown config that may be left by Cloud-init after its initialization.
# This must be done during each boot to avoid interferring with VyOS CLI config.

import logging
from pathlib import Path
from subprocess import run, DEVNULL
from cloudinit.settings import PER_ALWAYS

LOG = logging.getLogger(__name__)

frequency = PER_ALWAYS


# cleanup network interface config file added by cloud-init
def network_cleanup() -> None:
LOG.debug("Cleaning up network configuration applied by Cloud-Init")
net_config_file = Path("/etc/network/interfaces.d/50-cloud-init")
if net_config_file.exists():
LOG.debug(f"Configuration file {net_config_file} was found")
try:
# get a list of interfaces that need to be deconfigured
configured_ifaces: list[str] = (
run(
["ifquery", "-l", "-X", "lo", "-i", net_config_file],
capture_output=True,
)
.stdout.decode()
.splitlines()
)
if configured_ifaces:
for iface in configured_ifaces:
LOG.debug(f"Deconfiguring interface: {iface}")
run(["ifdown", iface], stdout=DEVNULL)
# delete the file
net_config_file.unlink()
LOG.debug(f"Configuration file {net_config_file} was removed")
except Exception as err:
LOG.error(f"Failed to cleanup network configuration: {err}")

udev_rules_file = Path("/etc/udev/rules.d/70-persistent-net.rules")
if udev_rules_file.exists():
LOG.debug(f"Configuration file {udev_rules_file} was removed")
udev_rules_file.unlink()


def handle(*args) -> None:
LOG.debug('Running "cc_vyos_ifupdown" module')
network_cleanup()
1 change: 1 addition & 0 deletions config/cloud.cfg.d/10_vyos.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ cloud_init_modules:

# The modules that run in the 'config' stage
cloud_config_modules:
- vyos_ifupdown
- vyos
- write_files
- vyos_userdata
Expand Down
Loading