github.com/portworx/docker@v1.12.1/pkg/aaparser/aaparser.go (about) 1 // Package aaparser is a convenience package interacting with `apparmor_parser`. 2 package aaparser 3 4 import ( 5 "fmt" 6 "os/exec" 7 "path/filepath" 8 "strconv" 9 "strings" 10 ) 11 12 const ( 13 binary = "apparmor_parser" 14 ) 15 16 // GetVersion returns the major and minor version of apparmor_parser. 17 func GetVersion() (int, error) { 18 output, err := cmd("", "--version") 19 if err != nil { 20 return -1, err 21 } 22 23 return parseVersion(output) 24 } 25 26 // LoadProfile runs `apparmor_parser -r -W` on a specified apparmor profile to 27 // replace and write it to disk. 28 func LoadProfile(profilePath string) error { 29 _, err := cmd(filepath.Dir(profilePath), "-r", "-W", filepath.Base(profilePath)) 30 if err != nil { 31 return err 32 } 33 return nil 34 } 35 36 // cmd runs `apparmor_parser` with the passed arguments. 37 func cmd(dir string, arg ...string) (string, error) { 38 c := exec.Command(binary, arg...) 39 c.Dir = dir 40 41 output, err := c.CombinedOutput() 42 if err != nil { 43 return "", fmt.Errorf("running `%s %s` failed with output: %s\nerror: %v", c.Path, strings.Join(c.Args, " "), string(output), err) 44 } 45 46 return string(output), nil 47 } 48 49 // parseVersion takes the output from `apparmor_parser --version` and returns 50 // a representation of the {major, minor, patch} version as a single number of 51 // the form MMmmPPP {major, minor, patch}. 52 func parseVersion(output string) (int, error) { 53 // output is in the form of the following: 54 // AppArmor parser version 2.9.1 55 // Copyright (C) 1999-2008 Novell Inc. 56 // Copyright 2009-2012 Canonical Ltd. 57 58 lines := strings.SplitN(output, "\n", 2) 59 words := strings.Split(lines[0], " ") 60 version := words[len(words)-1] 61 62 // split by major minor version 63 v := strings.Split(version, ".") 64 if len(v) == 0 || len(v) > 3 { 65 return -1, fmt.Errorf("parsing version failed for output: `%s`", output) 66 } 67 68 // Default the versions to 0. 69 var majorVersion, minorVersion, patchLevel int 70 71 majorVersion, err := strconv.Atoi(v[0]) 72 if err != nil { 73 return -1, err 74 } 75 76 if len(v) > 1 { 77 minorVersion, err = strconv.Atoi(v[1]) 78 if err != nil { 79 return -1, err 80 } 81 } 82 if len(v) > 2 { 83 patchLevel, err = strconv.Atoi(v[2]) 84 if err != nil { 85 return -1, err 86 } 87 } 88 89 // major*10^5 + minor*10^3 + patch*10^0 90 numericVersion := majorVersion*1e5 + minorVersion*1e3 + patchLevel 91 return numericVersion, nil 92 }