Skip to content

Commit

Permalink
tuned: controller: pack profilesExtract return values in struct
Browse files Browse the repository at this point in the history
xref: openshift#1019 (comment)

Signed-off-by: Francesco Romani <[email protected]>
  • Loading branch information
ffromani committed Jul 22, 2024
1 parent f00595e commit df66093
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
2 changes: 1 addition & 1 deletion pkg/tuned/cmd/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func render(inputDir []string, outputDir string, mcpName string) error {
for _, t := range tuneD {
tunedProfiles = append(tunedProfiles, t.Spec.Profile...)
}
_, _, _, _, err = tunedpkg.ProfilesExtract(tunedProfiles, recommendedProfile)
_, err = tunedpkg.ProfilesExtract(tunedProfiles, recommendedProfile)
if err != nil {
klog.Errorf("error extracting tuned profiles : %v", err)
return fmt.Errorf("error extracting tuned profiles: %w", err)
Expand Down
58 changes: 40 additions & 18 deletions pkg/tuned/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,15 +389,23 @@ func profilesEqual(profileFile string, profileData string) bool {
return profileData == string(content)
}

type ExtractedProfiles struct {
// True if the data in the to-be-extracted recommended profile or the profiles being
// included from the current recommended profile have changed.
Changed bool
// If the data changed, the fingerprint of the new profile, or "" otherwise.
Fingerprint string
// A map with successfully extracted TuneD profile names.
Names map[string]bool
// A map with names of TuneD profiles the current TuneD recommended profile depends on.
Dependencies map[string]bool
}

// ProfilesExtract extracts TuneD daemon profiles to tunedProfilesDirCustom directory.
// Returns:
// - True if the data in the to-be-extracted recommended profile or the profiles being
// included from the current recommended profile have changed.
// - If the data changed, the fingerprint of the new profile, or "" otherwise.
// - A map with successfully extracted TuneD profile names.
// - A map with names of TuneD profiles the current TuneD recommended profile depends on.
// - ExtractedProfile with the details of the operation performed
// - Error if any or nil.
func ProfilesExtract(profiles []tunedv1.TunedProfile, recommendedProfile string) (bool, string, map[string]bool, map[string]bool, error) {
func ProfilesExtract(profiles []tunedv1.TunedProfile, recommendedProfile string) (ExtractedProfiles, error) {
klog.Infof("profilesExtract(): extracting %d TuneD profiles (recommended=%s)", len(profiles), recommendedProfile)
// Get a list of TuneD profiles names the recommended profile depends on.
deps := profileDepends(recommendedProfile)
Expand All @@ -409,7 +417,7 @@ func ProfilesExtract(profiles []tunedv1.TunedProfile, recommendedProfile string)

// profilesExtractPathWithDeps is like ProfilesExtract but takes explicit profiles root dir path and
// explicit dependencies, so it's easier to test. To be used only internally.
func profilesExtractPathWithDeps(profilesRootDir string, profiles []tunedv1.TunedProfile, recommendedProfile string, recommendedProfileDeps map[string]bool) (bool, string, map[string]bool, map[string]bool, error) {
func profilesExtractPathWithDeps(profilesRootDir string, profiles []tunedv1.TunedProfile, recommendedProfile string, recommendedProfileDeps map[string]bool) (ExtractedProfiles, error) {
var (
change bool = false
extracted map[string]bool = map[string]bool{} // TuneD profile names present in TuneD CR and successfully extracted to tunedProfilesDirCustom
Expand All @@ -428,7 +436,11 @@ func profilesExtractPathWithDeps(profilesRootDir string, profiles []tunedv1.Tune
profileFile := filepath.Join(profileDir, tunedConfFile)

if err := os.MkdirAll(profileDir, os.ModePerm); err != nil {
return change, "", extracted, recommendedProfileDeps, fmt.Errorf("failed to create TuneD profile directory %q: %v", profileDir, err)
return ExtractedProfiles{
Changed: change,
Names: extracted,
Dependencies: recommendedProfileDeps,
}, fmt.Errorf("failed to create TuneD profile directory %q: %v", profileDir, err)
}

if recommendedProfileDeps[*profile.Name] {
Expand All @@ -444,15 +456,24 @@ func profilesExtractPathWithDeps(profilesRootDir string, profiles []tunedv1.Tune

err := os.WriteFile(profileFile, []byte(*profile.Data), 0644)
if err != nil {
return change, "", extracted, recommendedProfileDeps, fmt.Errorf("failed to write TuneD profile file %q: %v", profileFile, err)
return ExtractedProfiles{
Changed: change,
Names: extracted,
Dependencies: recommendedProfileDeps,
}, fmt.Errorf("failed to write TuneD profile file %q: %v", profileFile, err)
}
extracted[*profile.Name] = true
klog.V(2).Infof("profilesExtract(): extracted profile %q to %q (%d bytes)", *profile.Name, profileFile, len(*profile.Data))
}

profilesFP := profilesFingerprint(profiles, recommendedProfile)
klog.Infof("profilesExtract(): fingerprint of extracted profiles: %q", profilesFP)
return change, profilesFP, extracted, recommendedProfileDeps, nil
return ExtractedProfiles{
Changed: change,
Fingerprint: profilesFP,
Names: extracted,
Dependencies: recommendedProfileDeps,
}, nil
}

// profilesRepackPath reconstructs the TunedProfile object from the data unpacked on the node
Expand Down Expand Up @@ -506,16 +527,17 @@ func profilesRepackPath(recommendFilePath, profilesRootDir string) ([]tunedv1.Tu
// - The synced profile fingerprint.
// - Error if any or nil.
func profilesSync(profiles []tunedv1.TunedProfile, recommendedProfile string) (bool, string, error) {
change, profilesFP, extractedNew, recommendedProfileDeps, err := ProfilesExtract(profiles, recommendedProfile)
extracted, err := ProfilesExtract(profiles, recommendedProfile)
if err != nil {
return change, "", err
return extracted.Changed, "", err
}

dirEntries, err := os.ReadDir(tunedProfilesDirCustom)
if err != nil {
return change, "", err
return extracted.Changed, "", err
}

changed := extracted.Changed // shortcut, but we also modify before
// Deal with TuneD profiles absent from Tuned CRs, but still present in <tunedProfilesDirCustom>/<profile>/
for _, dirEntry := range dirEntries {
profile := dirEntry.Name()
Expand All @@ -529,26 +551,26 @@ func profilesSync(profiles []tunedv1.TunedProfile, recommendedProfile string) (b
continue
}

if extractedNew[profile] {
if extracted.Names[profile] {
// Do not delete the freshly extracted profiles. These are the profiles present in the Profile CR.
continue
}
// This TuneD profile does not exist in the Profile CR, delete it.
profileDir := fmt.Sprintf("%s/%s", tunedProfilesDirCustom, profile)
err := os.RemoveAll(profileDir)
if err != nil {
return change, "", fmt.Errorf("failed to remove %q: %v", profileDir, err)
return changed, "", fmt.Errorf("failed to remove %q: %v", profileDir, err)
}
klog.Infof("profilesSync(): removed TuneD profile %q", profileDir)

if recommendedProfileDeps[profile] {
if extracted.Dependencies[profile] {
// This TuneD profile does not exist in the Profile CR, but the recommended profile depends on it.
// Trigger a change to report a configuration issue -- we depend on a profile that does not exist.
change = true
changed = true
}
}

return change, profilesFP, nil
return changed, extracted.Fingerprint, nil
}

// filterAndSortProfiles returns a slice of valid (non-nil name, non-nil data) profiles
Expand Down

0 comments on commit df66093

Please sign in to comment.