diff --git a/apparmor/setup.go b/apparmor/setup.go index 4c664598..548e72f5 100644 --- a/apparmor/setup.go +++ b/apparmor/setup.go @@ -2,13 +2,17 @@ package apparmor import ( "fmt" + "io" "io/ioutil" "os" "os/exec" "path" ) -const DefaultProfilePath = "/etc/apparmor.d/docker" +const ( + DefaultProfilePath = "/etc/apparmor.d/docker" +) + const DefaultProfile = ` # AppArmor profile from lxc for containers. @@ -73,14 +77,38 @@ profile docker-default flags=(attach_disconnected,mediate_deleted) { } ` -func InstallDefaultProfile() error { +func InstallDefaultProfile(backupPath string) error { if !IsEnabled() { return nil } - // If the profile already exists, let it be. + // If the profile already exists, check if we already have a backup + // if not, do the backup and override it. (docker 0.10 upgrade changed the apparmor profile) + // see gh#5049, apparmor blocks signals in ubuntu 14.04 if _, err := os.Stat(DefaultProfilePath); err == nil { - return nil + if _, err := os.Stat(backupPath); err == nil { + // If both the profile and the backup are present, do nothing + return nil + } + // Make sure the directory exists + if err := os.MkdirAll(path.Dir(backupPath), 0755); err != nil { + return err + } + + // Create the backup file + f, err := os.Create(backupPath) + if err != nil { + return err + } + defer f.Close() + src, err := os.Open(DefaultProfilePath) + if err != nil { + return err + } + defer src.Close() + if _, err := io.Copy(f, src); err != nil { + return err + } } // Make sure /etc/apparmor.d exists