Skip to content

Commit f324d20

Browse files
authored
Merge pull request #1161 from stgraber/main
incusd/apparmor: Don't constantly query the version and cache
2 parents ffa7ecc + 2a1f209 commit f324d20

File tree

1 file changed

+47
-57
lines changed

1 file changed

+47
-57
lines changed

internal/server/apparmor/apparmor.go

+47-57
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,45 @@ const (
2121
cmdParse = "Q"
2222
)
2323

24+
var aaCacheDir string
2425
var aaPath = internalUtil.VarPath("security", "apparmor")
26+
var aaVersion *version.DottedVersion
27+
28+
func init() {
29+
// Fill in aaVersion.
30+
out, err := subprocess.RunCommand("apparmor_parser", "--version")
31+
if err != nil {
32+
return
33+
}
34+
35+
fields := strings.Fields(strings.Split(out, "\n")[0])
36+
parsedVersion, err := version.Parse(fields[len(fields)-1])
37+
if err != nil {
38+
return
39+
}
40+
41+
aaVersion = parsedVersion
42+
43+
// Fill in aaCacheDir.
44+
basePath := filepath.Join(aaPath, "cache")
45+
46+
// Multiple policy cache directories were only added in v2.13.
47+
minVer, err := version.NewDottedVersion("2.13")
48+
if err != nil {
49+
return
50+
}
51+
52+
if aaVersion.Compare(minVer) < 0 {
53+
aaCacheDir = basePath
54+
} else {
55+
output, err := subprocess.RunCommand("apparmor_parser", "-L", basePath, "--print-cache-dir")
56+
if err != nil {
57+
return
58+
}
59+
60+
aaCacheDir = strings.TrimSpace(output)
61+
}
62+
}
2563

2664
// runApparmor runs the relevant AppArmor command.
2765
func runApparmor(sysOS *sys.OS, command string, name string) error {
@@ -144,19 +182,18 @@ func deleteProfile(sysOS *sys.OS, fullName string, name string) error {
144182
return nil
145183
}
146184

147-
cacheDir, err := getCacheDir(sysOS)
148-
if err != nil {
149-
return err
185+
if aaCacheDir == "" {
186+
return fmt.Errorf("Couldn't identify AppArmor cache directory")
150187
}
151188

152-
err = unloadProfile(sysOS, fullName, name)
189+
err := unloadProfile(sysOS, fullName, name)
153190
if err != nil {
154191
return err
155192
}
156193

157-
err = os.Remove(filepath.Join(cacheDir, name))
194+
err = os.Remove(filepath.Join(aaCacheDir, name))
158195
if err != nil && !os.IsNotExist(err) {
159-
return fmt.Errorf("Failed to remove %s: %w", filepath.Join(cacheDir, name), err)
196+
return fmt.Errorf("Failed to remove %s: %w", filepath.Join(aaCacheDir, name), err)
160197
}
161198

162199
err = os.Remove(filepath.Join(aaPath, "profiles", name))
@@ -173,9 +210,8 @@ func parserSupports(sysOS *sys.OS, feature string) (bool, error) {
173210
return false, nil
174211
}
175212

176-
ver, err := getVersion(sysOS)
177-
if err != nil {
178-
return false, err
213+
if aaVersion == nil {
214+
return false, fmt.Errorf("Couldn't identify AppArmor version")
179215
}
180216

181217
if feature == "unix" {
@@ -184,7 +220,7 @@ func parserSupports(sysOS *sys.OS, feature string) (bool, error) {
184220
return false, err
185221
}
186222

187-
return ver.Compare(minVer) >= 0, nil
223+
return aaVersion.Compare(minVer) >= 0, nil
188224
}
189225

190226
if feature == "nosymfollow" {
@@ -193,58 +229,12 @@ func parserSupports(sysOS *sys.OS, feature string) (bool, error) {
193229
return false, err
194230
}
195231

196-
return ver.Compare(minVer) >= 0, nil
232+
return aaVersion.Compare(minVer) >= 0, nil
197233
}
198234

199235
return false, nil
200236
}
201237

202-
// getVersion reads and parses the AppArmor version.
203-
func getVersion(sysOS *sys.OS) (*version.DottedVersion, error) {
204-
if !sysOS.AppArmorAvailable {
205-
return version.NewDottedVersion("0.0")
206-
}
207-
208-
out, err := subprocess.RunCommand("apparmor_parser", "--version")
209-
if err != nil {
210-
return nil, err
211-
}
212-
213-
fields := strings.Fields(strings.Split(out, "\n")[0])
214-
return version.Parse(fields[len(fields)-1])
215-
}
216-
217-
// getCacheDir returns the applicable AppArmor cache directory.
218-
func getCacheDir(sysOS *sys.OS) (string, error) {
219-
basePath := filepath.Join(aaPath, "cache")
220-
221-
if !sysOS.AppArmorAvailable {
222-
return basePath, nil
223-
}
224-
225-
ver, err := getVersion(sysOS)
226-
if err != nil {
227-
return "", err
228-
}
229-
230-
// Multiple policy cache directories were only added in v2.13.
231-
minVer, err := version.NewDottedVersion("2.13")
232-
if err != nil {
233-
return "", err
234-
}
235-
236-
if ver.Compare(minVer) < 0 {
237-
return basePath, nil
238-
}
239-
240-
output, err := subprocess.RunCommand("apparmor_parser", "-L", basePath, "--print-cache-dir")
241-
if err != nil {
242-
return "", err
243-
}
244-
245-
return strings.TrimSpace(output), nil
246-
}
247-
248238
// profileName handles generating valid profile names.
249239
func profileName(prefix string, name string) string {
250240
separators := 1

0 commit comments

Comments
 (0)