Skip to content

Commit

Permalink
manifest: calculate raw kickstart test file content hash in test
Browse files Browse the repository at this point in the history
Instead of a static content hash for the raw kickstart file when
testing, calculate it on the fly using a hardcoded blob for the sudobits
and add any extra content that the user might have supplied so we can
test the user injected content as well.
  • Loading branch information
achilleas-k authored and thozza committed Apr 26, 2024
1 parent ff2cb0c commit bd6234b
Showing 1 changed file with 46 additions and 13 deletions.
59 changes: 46 additions & 13 deletions pkg/manifest/anaconda_installer_iso_tree_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manifest

import (
"crypto/sha256"
"fmt"
"math/rand"
"testing"
Expand Down Expand Up @@ -121,16 +122,48 @@ func findRawKickstartFileStage(stages []*osbuild.Stage) *osbuild.CopyStageOption
return nil
}

func checkKickstartUnattendedOptions(stages []*osbuild.Stage, sudobits bool) error {
const (
ksSudoContent = `%post
echo -e "%sudo\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/%sudo"
chmod 0440 /etc/sudoers.d/%sudo
echo -e "%wheel\tALL=(ALL)\tNOPASSWD: ALL" > "/etc/sudoers.d/%wheel"
chmod 0440 /etc/sudoers.d/%wheel
restorecon -rvF /etc/sudoers.d
%end
`
}

content += extra

func calculateInlineFileChecksum(parts ...string) string {
content := "%include /run/install/repo/test-base.ks\n"
for _, part := range parts {
content += "\n" + part
}
return fmt.Sprintf("%x", sha256.Sum256([]byte(content)))
}

func checkKickstartUnattendedOptions(stages []*osbuild.Stage, sudobits bool, extra string) error {

ksParts := make([]string, 0)
if sudobits {
ksParts = append(ksParts, ksSudoContent)
}
if extra != "" {
ksParts = append(ksParts, extra)
}

ksCopyStageOptions := findRawKickstartFileStage(stages)
if sudobits && ksCopyStageOptions == nil { // sudobits enabled - raw kickstart stage (file stage) should exist
return fmt.Errorf("expected raw kickstart file for sudoers but not found")
} else if !sudobits && ksCopyStageOptions != nil { // sudobits disabled - no raw kickstart file stage should be found
return fmt.Errorf("found raw kickstart file for sudoers but was not expected")
expRawFile := len(ksParts) > 0
if expRawFile && ksCopyStageOptions == nil { // raw kickstart stage (file stage) should exist
return fmt.Errorf("expected raw kickstart file but not found")
} else if !expRawFile && ksCopyStageOptions != nil { // no raw kickstart file stage should be found
return fmt.Errorf("found raw kickstart file but was not expected")
}

if ksCopyStageOptions != nil {
expContentID := "input://file-d9cb9d34781b23069d70465e2e00b7dc4a2e63cf4cf8559b8c09b13ef10ed592/sha256:d9cb9d34781b23069d70465e2e00b7dc4a2e63cf4cf8559b8c09b13ef10ed592"
contentHash := calculateInlineFileChecksum(ksParts...)
expContentID := fmt.Sprintf("input://file-%[1]s/sha256:%[1]s", contentHash)
// inline file IDs are the hash of their content so this is the hash of the expected content
if inlineID := ksCopyStageOptions.Paths[0].From; inlineID != expContentID {
return fmt.Errorf("raw kickstart content mismatch: %s != %s", expContentID, inlineID)
Expand All @@ -139,10 +172,10 @@ func checkKickstartUnattendedOptions(stages []*osbuild.Stage, sudobits bool) err

ksOptions := getKickstartOptions(stages)

// check the kickstart path depending on whether we have sudobits enabled
if sudobits && ksOptions.Path != testBaseKsPath {
// check the kickstart path depending on whether we have extra raw content included
if expRawFile && ksOptions.Path != testBaseKsPath {
return fmt.Errorf("kickstart file path should be %q but is %q", testBaseKsPath, ksOptions.Path)
} else if !sudobits && ksOptions.Path != testKsPath {
} else if !expRawFile && ksOptions.Path != testKsPath {
return fmt.Errorf("kickstart file path should be %q but is %q", testKsPath, ksOptions.Path)
}

Expand Down Expand Up @@ -260,7 +293,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
variantStages))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, false))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, false, ""))
})

t.Run("unattended+sudo", func(t *testing.T) {
Expand All @@ -277,7 +310,7 @@ func TestAnacondaISOTreeSerializeWithOS(t *testing.T) {
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux", "org.osbuild.kickstart"),
variantStages))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, true))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, true, ""))
})

}
Expand Down Expand Up @@ -330,7 +363,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, false))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, false, ""))
})

t.Run("unattended+sudo", func(t *testing.T) {
Expand All @@ -345,7 +378,7 @@ func TestAnacondaISOTreeSerializeWithOSTree(t *testing.T) {
sp := pipeline.serialize()
pipeline.serializeEnd()
assert.NoError(t, checkISOTreeStages(sp.Stages, append(payloadStages, "org.osbuild.isolinux"), variantStages))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, true))
assert.NoError(t, checkKickstartUnattendedOptions(sp.Stages, true, ""))
})
}

Expand Down

0 comments on commit bd6234b

Please sign in to comment.