setup.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package apparmor
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "os/exec"
  7. "path"
  8. )
  9. const (
  10. DefaultProfilePath = "/etc/apparmor.d/docker"
  11. )
  12. func InstallDefaultProfile(backupPath string) error {
  13. if !IsEnabled() {
  14. return nil
  15. }
  16. // If the profile already exists, check if we already have a backup
  17. // if not, do the backup and override it. (docker 0.10 upgrade changed the apparmor profile)
  18. // see gh#5049, apparmor blocks signals in ubuntu 14.04
  19. if _, err := os.Stat(DefaultProfilePath); err == nil {
  20. if _, err := os.Stat(backupPath); err == nil {
  21. // If both the profile and the backup are present, do nothing
  22. return nil
  23. }
  24. // Make sure the directory exists
  25. if err := os.MkdirAll(path.Dir(backupPath), 0755); err != nil {
  26. return err
  27. }
  28. // Create the backup file
  29. f, err := os.Create(backupPath)
  30. if err != nil {
  31. return err
  32. }
  33. defer f.Close()
  34. src, err := os.Open(DefaultProfilePath)
  35. if err != nil {
  36. return err
  37. }
  38. defer src.Close()
  39. if _, err := io.Copy(f, src); err != nil {
  40. return err
  41. }
  42. }
  43. // Make sure /etc/apparmor.d exists
  44. if err := os.MkdirAll(path.Dir(DefaultProfilePath), 0755); err != nil {
  45. return err
  46. }
  47. f, err := os.OpenFile(DefaultProfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
  48. if err != nil {
  49. return err
  50. }
  51. if err := generateProfile(f); err != nil {
  52. f.Close()
  53. return err
  54. }
  55. f.Close()
  56. cmd := exec.Command("/sbin/apparmor_parser", "-r", "-W", "docker")
  57. // to use the parser directly we have to make sure we are in the correct
  58. // dir with the profile
  59. cmd.Dir = "/etc/apparmor.d"
  60. output, err := cmd.CombinedOutput()
  61. if err != nil {
  62. return fmt.Errorf("Error loading docker apparmor profile: %s (%s)", err, output)
  63. }
  64. return nil
  65. }