зеркало из https://github.com/microsoft/docker.git
refactor aaparser pkg, add unit tests
Signed-off-by: Jessica Frazelle <acidburn@docker.com>
This commit is contained in:
Родитель
1393c450cd
Коммит
446f498eba
|
@ -4,7 +4,6 @@ package native
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -137,15 +136,10 @@ func installAppArmorProfile() error {
|
||||||
}
|
}
|
||||||
f.Close()
|
f.Close()
|
||||||
|
|
||||||
cmd := exec.Command("/sbin/apparmor_parser", "-r", "-W", "docker")
|
if err := aaparser.LoadProfile(apparmorProfilePath); err != nil {
|
||||||
// to use the parser directly we have to make sure we are in the correct
|
return err
|
||||||
// dir with the profile
|
|
||||||
cmd.Dir = "/etc/apparmor.d"
|
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Error loading docker apparmor profile: %s (%s)", err, output)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,66 @@
|
||||||
|
// Package aaparser is a convenience package interacting with `apparmor_parser`.
|
||||||
package aaparser
|
package aaparser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetVersion returns the major and minor version of apparmor_parser
|
const (
|
||||||
func GetVersion() (int, int, error) {
|
binary = "apparmor_parser"
|
||||||
// get the apparmor_version version
|
)
|
||||||
cmd := exec.Command("apparmor_parser", "--version")
|
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
// GetVersion returns the major and minor version of apparmor_parser.
|
||||||
|
func GetVersion() (int, int, error) {
|
||||||
|
output, err := cmd("", "--version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("getting apparmor_parser version failed: %s (%s)", err, output)
|
return -1, -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the version from the output
|
return parseVersion(string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadProfile runs `apparmor_parser -r -W` on a specified apparmor profile to
|
||||||
|
// replace and write it to disk.
|
||||||
|
func LoadProfile(profilePath string) error {
|
||||||
|
_, err := cmd(filepath.Dir(profilePath), "-r", "-W", filepath.Base(profilePath))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmd runs `apparmor_parser` with the passed arguments.
|
||||||
|
func cmd(dir string, arg ...string) (string, error) {
|
||||||
|
c := exec.Command(binary, arg...)
|
||||||
|
c.Dir = dir
|
||||||
|
|
||||||
|
output, err := c.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), string(output), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseVersion takes the output from `apparmor_parser --version` and returns
|
||||||
|
// the major and minor version for `apparor_parser`.
|
||||||
|
func parseVersion(output string) (int, int, error) {
|
||||||
// output is in the form of the following:
|
// output is in the form of the following:
|
||||||
// AppArmor parser version 2.9.1
|
// AppArmor parser version 2.9.1
|
||||||
// Copyright (C) 1999-2008 Novell Inc.
|
// Copyright (C) 1999-2008 Novell Inc.
|
||||||
// Copyright 2009-2012 Canonical Ltd.
|
// Copyright 2009-2012 Canonical Ltd.
|
||||||
lines := strings.SplitN(string(output), "\n", 2)
|
lines := strings.SplitN(output, "\n", 2)
|
||||||
words := strings.Split(lines[0], " ")
|
words := strings.Split(lines[0], " ")
|
||||||
version := words[len(words)-1]
|
version := words[len(words)-1]
|
||||||
|
|
||||||
// split by major minor version
|
// split by major minor version
|
||||||
v := strings.Split(version, ".")
|
v := strings.Split(version, ".")
|
||||||
if len(v) < 2 {
|
if len(v) < 2 {
|
||||||
return -1, -1, fmt.Errorf("parsing major minor version failed for %q", version)
|
return -1, -1, fmt.Errorf("parsing major minor version failed for output: `%s`", output)
|
||||||
}
|
}
|
||||||
|
|
||||||
majorVersion, err := strconv.Atoi(v[0])
|
majorVersion, err := strconv.Atoi(v[0])
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package aaparser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type versionExpected struct {
|
||||||
|
output string
|
||||||
|
major int
|
||||||
|
minor int
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseVersion(t *testing.T) {
|
||||||
|
versions := []versionExpected{
|
||||||
|
{
|
||||||
|
output: `AppArmor parser version 2.10
|
||||||
|
Copyright (C) 1999-2008 Novell Inc.
|
||||||
|
Copyright 2009-2012 Canonical Ltd.
|
||||||
|
|
||||||
|
`,
|
||||||
|
major: 2,
|
||||||
|
minor: 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
output: `AppArmor parser version 2.8
|
||||||
|
Copyright (C) 1999-2008 Novell Inc.
|
||||||
|
Copyright 2009-2012 Canonical Ltd.
|
||||||
|
|
||||||
|
`,
|
||||||
|
major: 2,
|
||||||
|
minor: 8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
output: `AppArmor parser version 2.20
|
||||||
|
Copyright (C) 1999-2008 Novell Inc.
|
||||||
|
Copyright 2009-2012 Canonical Ltd.
|
||||||
|
|
||||||
|
`,
|
||||||
|
major: 2,
|
||||||
|
minor: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
output: `AppArmor parser version 2.05
|
||||||
|
Copyright (C) 1999-2008 Novell Inc.
|
||||||
|
Copyright 2009-2012 Canonical Ltd.
|
||||||
|
|
||||||
|
`,
|
||||||
|
major: 2,
|
||||||
|
minor: 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range versions {
|
||||||
|
major, minor, err := parseVersion(v.output)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected error to be nil for %#v, got: %v", v, err)
|
||||||
|
}
|
||||||
|
if major != v.major {
|
||||||
|
t.Fatalf("expected major version to be %d, was %d, for: %#v\n", v.major, major, v)
|
||||||
|
}
|
||||||
|
if minor != v.minor {
|
||||||
|
t.Fatalf("expected minor version to be %d, was %d, for: %#v\n", v.minor, minor, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче