(name string)
| 115 | } |
| 116 | |
| 117 | func loadData(name string) (*data, error) { |
| 118 | p := data{ |
| 119 | Name: name, |
| 120 | } |
| 121 | |
| 122 | const abi = "abi/3.0" |
| 123 | if macroExists(abi) { |
| 124 | p.Abi = abi |
| 125 | } |
| 126 | |
| 127 | if macroExists("tunables/global") { |
| 128 | p.Imports = append(p.Imports, "#include <tunables/global>") |
| 129 | } else { |
| 130 | p.Imports = append(p.Imports, "@{PROC}=/proc/") |
| 131 | } |
| 132 | if macroExists("abstractions/base") { |
| 133 | p.InnerImports = append(p.InnerImports, "#include <abstractions/base>") |
| 134 | } |
| 135 | |
| 136 | // Figure out the daemon profile. |
| 137 | currentProfile, err := os.ReadFile("/proc/self/attr/current") |
| 138 | if err != nil { |
| 139 | // If we couldn't get the daemon profile, assume we are running |
| 140 | // unconfined which is generally the default. |
| 141 | currentProfile = nil |
| 142 | } |
| 143 | p.DaemonProfile = cleanProfileName(string(currentProfile)) |
| 144 | |
| 145 | // If we were running in Rootless mode, we could read `/proc/$(cat ${ROOTLESSKIT_STATE_DIR}/child_pid)/exe`, |
| 146 | // but `nerdctl apparmor load` has to be executed as the root. |
| 147 | // So, do not check ${ROOTLESSKIT_STATE_DIR} (nor EUID) here. |
| 148 | p.RootlessKit, err = exec.LookPath("rootlesskit") |
| 149 | if err != nil { |
| 150 | log.L.WithError(err).Debug("apparmor: failed to determine the RootlessKit binary path") |
| 151 | p.RootlessKit = "" |
| 152 | } |
| 153 | log.L.Debugf("apparmor: RootlessKit=%q", p.RootlessKit) |
| 154 | |
| 155 | return &p, nil |
| 156 | } |
| 157 | |
| 158 | func generate(p *data, o io.Writer) error { |
| 159 | t, err := template.New("apparmor_profile").Parse(defaultTemplate) |
no test coverage detected
searching dependent graphs…