// End will stop the current build. An error will be returned if no build is in // progress. func (a *ACBuild) End() error { _, err := os.Stat(a.ContextPath) switch { case os.IsNotExist(err): return errNoBuildInProgress case err != nil: return err } if err = a.lock(); err != nil { return err } err = util.MaybeUnmount(a.OverlayTargetPath) if err != nil { return err } err = os.RemoveAll(a.ContextPath) if err != nil { return err } return nil }
// Run will execute the given command in the ACI being built. a.CurrentACIPath // is where the untarred ACI is stored, a.DepStoreTarPath is the directory to // download dependencies into, a.DepStoreExpandedPath is where the dependencies // are expanded into, and a.OverlayWorkPath is the work directory used by // overlayfs. // // Arguments: // // - cmd: The command to run and its arguments. // // - workingDir: If specified, the current directory inside the container is // changed to its value before running the given command. // // - runEngine: The engine used to perform the execution of the command. func (a *ACBuild) Run(cmd []string, workingDir string, insecure bool, runEngine engine.Engine) (err error) { if err = a.lock(); err != nil { return err } defer func() { if err1 := a.unlock(); err == nil { err = err1 } }() if os.Geteuid() != 0 { return fmt.Errorf("the run subcommand must be run as root") } if len(cmd) == 0 { return fmt.Errorf("command to run not set") } err = util.MaybeUnmount(a.OverlayTargetPath) if err != nil { return err } err = util.RmAndMkdir(a.OverlayTargetPath) if err != nil { return err } defer os.RemoveAll(a.OverlayTargetPath) err = util.RmAndMkdir(a.OverlayWorkPath) if err != nil { return err } defer os.RemoveAll(a.OverlayWorkPath) err = os.MkdirAll(a.DepStoreExpandedPath, 0755) if err != nil { return err } err = os.MkdirAll(a.DepStoreTarPath, 0755) if err != nil { return err } man, err := util.GetManifest(a.CurrentACIPath) if err != nil { return err } if len(man.Dependencies) != 0 { if !supportsOverlay() { err := exec.Command("modprobe", "overlay").Run() if err != nil { if _, ok := err.(*exec.ExitError); ok { return fmt.Errorf("overlayfs is not supported on your system") } return err } if !supportsOverlay() { return fmt.Errorf( "overlayfs support required for using run with dependencies") } } } deps, err := a.renderACI(insecure, a.Debug) if err != nil { return err } var chrootDir string if deps == nil { chrootDir = path.Join(a.CurrentACIPath, aci.RootfsDir) } else { for i, dep := range deps { deps[i] = path.Join(a.DepStoreExpandedPath, dep, aci.RootfsDir) } options := "lowerdir=" + strings.Join(deps, ":") + ",upperdir=" + path.Join(a.CurrentACIPath, aci.RootfsDir) + ",workdir=" + a.OverlayWorkPath err := syscall.Mount("overlay", a.OverlayTargetPath, "overlay", 0, options) if err != nil { return err } defer func() { err1 := syscall.Unmount(a.OverlayTargetPath, 0) if err == nil { err = err1 } }() chrootDir = a.OverlayTargetPath } var env types.Environment if man.App != nil { env = man.App.Environment } else { env = types.Environment{} } err = a.mirrorLocalZoneInfo() if err != nil { return err } err = runEngine.Run(cmd[0], cmd[1:], env, chrootDir, workingDir) if err != nil { return err } return nil }