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

internal/exec: delete enablement symlinks when disabling unit #1352

Merged
merged 1 commit into from
May 6, 2022
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
50 changes: 26 additions & 24 deletions internal/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ var (
systemConfigDir = "/usr/lib/ignition"

// Helper programs
groupaddCmd = "groupadd"
groupdelCmd = "groupdel"
mdadmCmd = "mdadm"
mountCmd = "mount"
sgdiskCmd = "sgdisk"
modprobeCmd = "modprobe"
udevadmCmd = "udevadm"
usermodCmd = "usermod"
useraddCmd = "useradd"
userdelCmd = "userdel"
setfilesCmd = "setfiles"
wipefsCmd = "wipefs"
groupaddCmd = "groupadd"
groupdelCmd = "groupdel"
mdadmCmd = "mdadm"
mountCmd = "mount"
sgdiskCmd = "sgdisk"
modprobeCmd = "modprobe"
udevadmCmd = "udevadm"
usermodCmd = "usermod"
useraddCmd = "useradd"
userdelCmd = "userdel"
setfilesCmd = "setfiles"
wipefsCmd = "wipefs"
systemctlCmd = "systemctl"

// Filesystem tools
btrfsMkfsCmd = "mkfs.btrfs"
Expand Down Expand Up @@ -84,18 +85,19 @@ func KernelCmdlinePath() string { return kernelCmdlinePath }
func BootIDPath() string { return bootIDPath }
func SystemConfigDir() string { return fromEnv("SYSTEM_CONFIG_DIR", systemConfigDir) }

func GroupaddCmd() string { return groupaddCmd }
func GroupdelCmd() string { return groupdelCmd }
func MdadmCmd() string { return mdadmCmd }
func MountCmd() string { return mountCmd }
func SgdiskCmd() string { return sgdiskCmd }
func ModprobeCmd() string { return modprobeCmd }
func UdevadmCmd() string { return udevadmCmd }
func UsermodCmd() string { return usermodCmd }
func UseraddCmd() string { return useraddCmd }
func UserdelCmd() string { return userdelCmd }
func SetfilesCmd() string { return setfilesCmd }
func WipefsCmd() string { return wipefsCmd }
func GroupaddCmd() string { return groupaddCmd }
func GroupdelCmd() string { return groupdelCmd }
func MdadmCmd() string { return mdadmCmd }
func MountCmd() string { return mountCmd }
func SgdiskCmd() string { return sgdiskCmd }
func ModprobeCmd() string { return modprobeCmd }
func UdevadmCmd() string { return udevadmCmd }
func UsermodCmd() string { return usermodCmd }
func UseraddCmd() string { return useraddCmd }
func UserdelCmd() string { return userdelCmd }
func SetfilesCmd() string { return setfilesCmd }
func WipefsCmd() string { return wipefsCmd }
func SystemctlCmd() string { return systemctlCmd }

func BtrfsMkfsCmd() string { return btrfsMkfsCmd }
func Ext4MkfsCmd() string { return ext4MkfsCmd }
Expand Down
19 changes: 19 additions & 0 deletions internal/exec/util/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import (
"fmt"
"net/url"
"os"
"os/exec"
"path/filepath"
"syscall"

"github.com/coreos/ignition/v2/config/v3_4_experimental/types"
"github.com/coreos/ignition/v2/internal/distro"

"github.com/vincent-petithory/dataurl"
)
Expand Down Expand Up @@ -151,6 +153,23 @@ func (ut Util) EnableUnit(enabledUnit string) error {
}

func (ut Util) DisableUnit(disabledUnit string) error {
// We need to delete any enablement symlinks for a unit before sending it to a
// preset directive. This will help to disable that unit completely.
// For more information: https://github.com/coreos/fedora-coreos-tracker/issues/392
// This is a short-term solution until the upstream systemd PR
// (https://github.com/systemd/systemd/pull/15205) gets accepted.
if err := ut.Logger.LogOp(
func() error {
args := []string{"--root", ut.DestDir, "disable", disabledUnit}
if output, err := exec.Command(distro.SystemctlCmd(), args...).CombinedOutput(); err != nil {
return fmt.Errorf("cannot remove symlink(s) for %s: %v: %q", disabledUnit, err, string(output))
}
return nil
},
"removing enablement symlink(s) for %q", disabledUnit,
); err != nil {
return err
}
return ut.appendLineToPreset(fmt.Sprintf("disable %s", disabledUnit))
}

Expand Down
61 changes: 61 additions & 0 deletions tests/positive/files/units.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func init() {
register.Register(register.PositiveTest, CreateEmptyDropinsUnit())
register.Register(register.PositiveTest, TestUnmaskUnit())
register.Register(register.PositiveTest, TestMaskUnit())
register.Register(register.PositiveTest, RemoveEnablementSymLinksforUnit())
}

func CreateInstantiatedService() types.Test {
Expand Down Expand Up @@ -259,3 +260,63 @@ func TestMaskUnit() types.Test {
ConfigMinVersion: configMinVersion,
}
}

// RemoveEnablementSymLinksforUnit checks if Ignition
// removes the enablement symlink for a given systemd
// unit marked as disabled. Also, verifies that the code
// doesn't error out when a non-existent unit marked as
// disabled.
func RemoveEnablementSymLinksforUnit() types.Test {
sohankunkerkar marked this conversation as resolved.
Show resolved Hide resolved
name := "unit.remove.symlinks"
in := types.GetBaseDisk()
out := types.GetBaseDisk()
config := `{
"ignition": { "version": "$version" },
"systemd": {
"units": [
{
"enabled": false,
"name": "foo.service"
},
{
"enabled": false,
"name": "enoent.service"
}
]
}
}`
in[0].Partitions.AddLinks("ROOT", []types.Link{
{
Node: types.Node{
Directory: "/etc/systemd/system/multi-user.target.wants",
Name: "foo.service",
},
Target: "/usr/lib/systemd/system/foo.service",
Hard: false,
},
})
in[0].Partitions.AddFiles("ROOT", []types.File{
{
Node: types.Node{
Name: "foo.service",
Directory: "usr/lib/systemd/system",
},
Contents: "[Unit]\nDescription=f\n[Service]\nType=oneshot\nExecStart=/usr/bin/true\n[Install]\nWantedBy=multi-user.target\n",
},
})
out[0].Partitions.AddRemovedNodes("ROOT", []types.Node{
{
Directory: "/etc/systemd/system/multi-user.target.wants",
Name: "foo.service",
},
})
configMinVersion := "3.0.0"

return types.Test{
Name: name,
In: in,
Out: out,
Config: config,
ConfigMinVersion: configMinVersion,
}
}