Install systemd-resolved for NetworkManager
Workaround for cloud-init bug until this fix gets shipped to the
distros:
cb36bf38b8
This commit is contained in:
parent
08d3ec2804
commit
a903d9ba0c
|
@ -39,11 +39,52 @@ func (mgr *OpensuseTumbleweedTemplateManager) DownloadTemplate(version, codename
|
|||
)
|
||||
}
|
||||
|
||||
func (mgr *OpensuseTumbleweedTemplateManager) InstallNetworkManager(handle *guestfs.Guestfs) error {
|
||||
args := []string{"zypper", "--non-interactive", "install", "NetworkManager"}
|
||||
_, err := mgr.logAndRunCommand(handle, args)
|
||||
func (mgr *OpensuseTumbleweedTemplateManager) addSystemUser(handle *guestfs.Guestfs, name, comment string) error {
|
||||
matches, err := handle.Grep("^"+name, "/etc/passwd", nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not install NetworkManager: %w", err)
|
||||
return fmt.Errorf("Could not grep /etc/passwd: %w", err)
|
||||
}
|
||||
if len(matches) > 0 {
|
||||
return nil
|
||||
}
|
||||
_, err = mgr.logAndRunCommand(handle, []string{
|
||||
"useradd",
|
||||
"--system",
|
||||
"--no-create-home",
|
||||
"--home-dir", "/",
|
||||
"--shell", "/usr/sbin/nologin",
|
||||
"--comment", comment,
|
||||
name,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not add user %s: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mgr *OpensuseTumbleweedTemplateManager) InstallSystemdResolved(handle *guestfs.Guestfs) error {
|
||||
// This package contains both systemd-networkd and systemd-resolved
|
||||
args := []string{"zypper", "--non-interactive", "install", "systemd-network"}
|
||||
if _, err := mgr.logAndRunCommand(handle, args); err != nil {
|
||||
return fmt.Errorf("Could not install systemd-network: %w", err)
|
||||
}
|
||||
// The systemd-network and systemd-resolve users don't get added for
|
||||
// some reason, even though the systemd services need to run as them
|
||||
if err := mgr.addSystemUser(handle, "systemd-resolve", "systemd Resolver"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := mgr.addSystemUser(handle, "systemd-network", "systemd Network Management"); err != nil {
|
||||
return err
|
||||
}
|
||||
// nsswitch.conf doesn't get updated either
|
||||
args = []string{
|
||||
"sed",
|
||||
"-i",
|
||||
`s/^hosts:/hosts:\t\tfiles myhostname resolve [!UNAVAIL=return] dns/`,
|
||||
"/usr/etc/nsswitch.conf",
|
||||
}
|
||||
if _, err := mgr.logAndRunCommand(handle, args); err != nil {
|
||||
return fmt.Errorf("Could not update nsswitch.conf: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -56,14 +56,14 @@ type IDistroSpecificTemplateManager interface {
|
|||
// (but does not upgrade) the packages for this distro, e.g.
|
||||
// "sudo apt update".
|
||||
CommandToUpdatePackageCache() []string
|
||||
// InstallNetworkManager installs the OS-specific package for
|
||||
// NetworkManager.
|
||||
InstallNetworkManager(handle *guestfs.Guestfs) error
|
||||
// InstallSystemdResolved installs the OS-specific package for
|
||||
// systemd-resolved.
|
||||
InstallSystemdResolved(handle *guestfs.Guestfs) error
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) InstallNetworkManager(handle *guestfs.Guestfs) error {
|
||||
func (mgr *TemplateManager) InstallSystemdResolved(handle *guestfs.Guestfs) error {
|
||||
// Individual distros should override this method if necessary
|
||||
return errors.New("InstallNetworkManager: not implemented for this distro")
|
||||
return errors.New("InstallSystemdResolved: not implemented for this distro")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) DownloadTemplateGeneric(filename, url string) (path string, err error) {
|
||||
|
@ -248,9 +248,12 @@ func (mgr *TemplateManager) logAndRunCommand(handle *guestfs.Guestfs, args []str
|
|||
}
|
||||
|
||||
func (mgr *TemplateManager) enableSystemdUnit(handle *guestfs.Guestfs, unit string) error {
|
||||
_, err := mgr.logAndRunCommand(handle, []string{
|
||||
"systemctl", "enable", unit,
|
||||
})
|
||||
_, err := mgr.logAndRunCommand(handle, []string{"systemctl", "enable", unit})
|
||||
return err
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) disableSystemdUnit(handle *guestfs.Guestfs, unit string) error {
|
||||
_, err := mgr.logAndRunCommand(handle, []string{"systemctl", "disable", unit})
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -440,6 +443,35 @@ func (mgr *TemplateManager) setNetworkManagerOptions(handle *guestfs.Guestfs) er
|
|||
return fmt.Errorf("Could not create %s: %w", cfgFilePath, err)
|
||||
}
|
||||
}
|
||||
// A bug was introduced in cloud-init commit 5942f40 which causes the DHCP
|
||||
// server identifier in the dhclient lease file to be ignored. It is fixed by
|
||||
// https://github.com/canonical/cloud-init/commit/cb36bf38b823f811a3e938ccffc03d7d13190095,
|
||||
// but as of this writing (2024-01-13), this fix is not present in any official
|
||||
// distro packages yet.
|
||||
// As a workaround, we will install systemd-resolved, whose NSS module
|
||||
// nss-resolve has a higher priority than "dns" for the "hosts" database in
|
||||
// nsswitch.conf. This allows cloud-init to resolve the "data-server" host name
|
||||
// (by querying the CloudStack DNS server instead of the ones which we wrote in
|
||||
// /etc/resolv.conf), so it will not need to read any DHCP lease files.
|
||||
// We can remove this workaround once the aforementioned fix gets shipped to
|
||||
// all of the distros which we support.
|
||||
resolvedIsPresent, err := handle.Is_file("/lib/systemd/systemd-resolved", nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not determine if /lib/systemd/systemd-resolved is a file: %w", err)
|
||||
}
|
||||
if !resolvedIsPresent {
|
||||
if err = mgr.impl.InstallSystemdResolved(handle); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = mgr.enableSystemdUnit(handle, "systemd-resolved"); err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure that systemd-networkd isn't enabled or else it'll interfere
|
||||
// with NetworkManager
|
||||
if err = mgr.disableSystemdUnit(handle, "systemd-networkd"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -466,20 +498,6 @@ func (mgr *TemplateManager) addSystemdNetworkdCloudInitSnippet(handle *guestfs.G
|
|||
return handle.Write(path, getResource("systemd-networkd-cloud-init"))
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) installAndEnableNetworkManager(handle *guestfs.Guestfs) error {
|
||||
isInstalled, err := handle.Is_file("/lib/systemd/system/NetworkManager.service", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isInstalled {
|
||||
err = mgr.impl.InstallNetworkManager(handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return mgr.enableSystemdUnit(handle, "NetworkManager.service")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setupCommonNetworkConfigs(handle *guestfs.Guestfs) error {
|
||||
usesNetworkManager, err := mgr.usesNetworkManager(handle)
|
||||
if err != nil {
|
||||
|
@ -502,12 +520,7 @@ func (mgr *TemplateManager) setupCommonNetworkConfigs(handle *guestfs.Guestfs) e
|
|||
if usesEtcNetworkInterfaces {
|
||||
return mgr.setDhclientOptions(handle)
|
||||
}
|
||||
mgr.logger.Info().Msg("Could not determine network backend, resorting to installing NetworkManager")
|
||||
err = mgr.installAndEnableNetworkManager(handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return mgr.setNetworkManagerOptions(handle)
|
||||
return errors.New("Could not determine network backend")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setupIpv6Scripts(handle *guestfs.Guestfs) (err error) {
|
||||
|
|
Loading…
Reference in New Issue