Skip to content

Commit

Permalink
Backup and restore start-stop-daemon and initctl to prevent more serv…
Browse files Browse the repository at this point in the history
…ices from starting during package installation
  • Loading branch information
upils committed Feb 6, 2024
1 parent 5c2d404 commit 190126f
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 2 deletions.
47 changes: 45 additions & 2 deletions internal/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ import (
)

// define some functions that can be mocked by test cases
var osRename = os.Rename
var osRemove = os.Remove
var (
osRename = os.Rename
osRemove = os.Remove
osWriteFile = os.WriteFile
osutilFileExists = osutil.FileExists
)

func BoolPtr(b bool) *bool {
return &b
Expand Down Expand Up @@ -492,3 +496,42 @@ func RestoreResolvConf(chroot string) error {
}
return nil
}

const backupExt = ".REAL"

// BackupReplace backup the target file and replace it with the given content
// Returns the restore function.
func BackupReplace(target string, content string) (func(error) error, error) {
backup := target + backupExt
if osutilFileExists(backup) {
// already backed up so do nothing
return nil, nil
}

if err := osRename(target, backup); err != nil {
return nil, fmt.Errorf("Error moving file \"%s\" to \"%s\": %s", target, backup, err.Error())
}

if err := osWriteFile(target, []byte(content), 0755); err != nil {
return nil, fmt.Errorf("Error writing to %s : %s", target, err.Error())
}

return genRestoreFile(target), nil
}

// genRestoreFile returns the function to be called to restore the backuped file
func genRestoreFile(target string) func(err error) error {
return func(err error) error {
src := target + backupExt
if !osutilFileExists(src) {
return err
}

if tmpErr := osRename(src, target); tmpErr != nil {
tmpErr = fmt.Errorf("Error moving file \"%s\" to \"%s\": %s", src, target, tmpErr.Error())
return fmt.Errorf("%s\n%s", err, tmpErr)
}

return err
}
}
22 changes: 22 additions & 0 deletions internal/statemachine/classic_states.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,28 @@ func (stateMachine *StateMachine) installPackages() error {
err = unsetDenyingPolicyRcD(err)
}()

restoreStartStopDaemon, err := backupReplaceStartStopDaemon(classicStateMachine.tempDirs.chroot)
if err != nil {
return err
}

defer func() {
err = restoreStartStopDaemon(err)
}()

initctlPath := filepath.Join(classicStateMachine.tempDirs.chroot, "sbin", "initctl")

if osutil.FileExists(initctlPath) {
restoreInitctl, err := backupReplaceInitctl(classicStateMachine.tempDirs.chroot)
if err != nil {
return err
}

defer func() {
err = restoreInitctl(err)
}()
}

installPackagesCmds := generateAptCmds(stateMachine.tempDirs.chroot, classicStateMachine.Packages)

err = helper.RunCmds(installPackagesCmds, classicStateMachine.commonFlags.Debug)
Expand Down
25 changes: 25 additions & 0 deletions internal/statemachine/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,31 @@ func dpkgDivert(baseDir string, target string) (*exec.Cmd, *exec.Cmd) {
return execCommand("chroot", divert...), execCommand("chroot", undivert...)
}

// backupReplaceStartStopDaemon backup start-stop-daemon and replace it with a fake one
// Returns a restore function to put the original one in place
func backupReplaceStartStopDaemon(baseDir string) (func(error) error, error) {
const startStopDaemonContent = `#!/bin/sh
echo
echo "Warning: Fake start-stop-daemon called, doing nothing"
`

startStopDaemon := filepath.Join(baseDir, "sbin", "start-stop-daemon")
return helper.BackupReplace(startStopDaemon, startStopDaemonContent)
}

// backupReplaceInitctl backup initctl and replace it with a fake one
// Returns a restore function to put the original one in place
func backupReplaceInitctl(baseDir string) (func(error) error, error) {
const initctlContent = `#!/bin/sh
if [ "$1" = version ]; then exec /sbin/initctl.REAL "$@"; fi
echo
echo "Warning: Fake initctl called, doing nothing"
`

initctl := filepath.Join(baseDir, "sbin", "initctl")
return helper.BackupReplace(initctl, initctlContent)
}

// createPPAInfo generates the name for a PPA sources.list file
// in the convention of add-apt-repository, and the contents
// that define the sources.list in the DEB822 format
Expand Down

0 comments on commit 190126f

Please sign in to comment.