Example #1
0
// 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
}
Example #2
0
// 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
}