Skip to content

Commit

Permalink
internal/exec: delete enablement symlinks when disabling unit
Browse files Browse the repository at this point in the history
FCOS ships some pre-created enablement symlinks, and the systemd
does nothing even after recording in the preset that they should be
removed. In order to fix this behavior, we're not only deleting
enablement symlinks for a given unit but also recording in the preset
directive to disable that unit completely. This is a short-term solution
until the upstream systemd PR (systemd/systemd#15205)
gets accepted.

Fixes coreos/fedora-coreos-tracker#392
  • Loading branch information
sohankunkerkar committed May 6, 2022
1 parent 9297e87 commit b5f33d2
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
2 changes: 2 additions & 0 deletions internal/distro/distro.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ var (
userdelCmd = "userdel"
setfilesCmd = "setfiles"
wipefsCmd = "wipefs"
systemtlCmd = "systemctl"

// Filesystem tools
btrfsMkfsCmd = "mkfs.btrfs"
Expand Down Expand Up @@ -96,6 +97,7 @@ func UseraddCmd() string { return useraddCmd }
func UserdelCmd() string { return userdelCmd }
func SetfilesCmd() string { return setfilesCmd }
func WipefsCmd() string { return wipefsCmd }
func SystemCtl() string { return systemtlCmd }

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.SystemCtl(), 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 {
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,
}
}

0 comments on commit b5f33d2

Please sign in to comment.