Beispiel #1
0
func (c *Compilator) isPackageCompiled(pkg *model.Package) (bool, error) {
	// If compiled package exists on hard disk
	compiledPackagePath := pkg.GetPackageCompiledDir(c.hostWorkDir)
	compiledPackagePathExists, err := validatePath(compiledPackagePath, true, "package path")
	if err != nil {
		return false, err
	}

	if !compiledPackagePathExists {
		return false, nil
	}

	compiledDirEmpty, err := isDirEmpty(compiledPackagePath)
	if err != nil {
		return false, err
	}

	return !compiledDirEmpty, nil
}
Beispiel #2
0
func (c *Compilator) getSourcePackageDir(pkg *model.Package) string {
	return filepath.Join(pkg.GetTargetPackageSourcesDir(c.hostWorkDir), "var", "vcap", "source")
}
Beispiel #3
0
func (c *Compilator) compilePackage(pkg *model.Package) (err error) {
	// Prepare input dir (package plus deps)
	if err := c.createCompilationDirStructure(pkg); err != nil {
		return err
	}

	if err := c.copyDependencies(pkg); err != nil {
		return err
	}

	// Generate a compilation script
	targetScriptName := "compile.sh"
	hostScriptPath := filepath.Join(pkg.GetTargetPackageSourcesDir(c.hostWorkDir), targetScriptName)
	containerScriptPath := filepath.Join(docker.ContainerInPath, targetScriptName)
	if err := compilation.SaveScript(c.baseType, compilation.CompilationScript, hostScriptPath); err != nil {
		return err
	}

	// Extract package
	extractDir := c.getSourcePackageDir(pkg)
	if _, err := pkg.Extract(extractDir); err != nil {
		return err
	}

	// Run compilation in container
	containerName := c.getPackageContainerName(pkg)

	// in-memory buffer of the log
	log := new(bytes.Buffer)

	stdoutWriter := docker.NewFormattingWriter(
		log,
		func(line string) string {
			return color.GreenString("compilation-%s > %s", color.MagentaString("%s", pkg.Name), color.WhiteString("%s", line))
		},
	)
	stderrWriter := docker.NewFormattingWriter(
		log,
		func(line string) string {
			return color.GreenString("compilation-%s > %s", color.MagentaString("%s", pkg.Name), color.RedString("%s", line))
		},
	)
	sourceMountName := fmt.Sprintf("source_mount-%s", uuid.New())
	mounts := map[string]string{
		pkg.GetTargetPackageSourcesDir(c.hostWorkDir): docker.ContainerInPath,
		pkg.GetPackageCompiledTempDir(c.hostWorkDir):  docker.ContainerOutPath,
		// Add the volume mount to work around AUFS issues.  We will clean
		// the volume up (as long as we're not trying to keep the container
		// around for debugging).  We don't give it an actual directory to mount
		// from, so it will be in some docker-maintained storage.
		sourceMountName: ContainerSourceDir,
	}
	exitCode, container, err := c.dockerManager.RunInContainer(docker.RunInContainerOpts{
		ContainerName: containerName,
		ImageName:     c.BaseImageName(),
		Cmd:           []string{"bash", containerScriptPath, pkg.Name, pkg.Version},
		Mounts:        mounts,
		Volumes:       map[string]map[string]string{sourceMountName: nil},
		KeepContainer: c.keepContainer,
		StdoutWriter:  stdoutWriter,
		StderrWriter:  stderrWriter,
	})

	if container != nil && (!c.keepContainer || err == nil || exitCode == 0) {
		// Attention. While the assignments to 'err' in the
		// deferal below take effect after the 'return'
		// statements coming later they are visible to the
		// caller, i.e.  override the 'return'ed value,
		// because 'err' is a __named__ return parameter.
		defer func() {
			// Remove container - dockerManager.RemoveContainer does a force-rm

			if removeErr := c.dockerManager.RemoveContainer(container.ID); removeErr != nil {
				if err == nil {
					err = removeErr
				} else {
					err = fmt.Errorf("Error compiling package: %s. Error removing package: %s", err.Error(), removeErr.Error())
				}
			}

			if removeErr := c.dockerManager.RemoveVolumes(container); removeErr != nil {
				if err == nil {
					err = removeErr
				} else {
					err = fmt.Errorf("%s: Error removing volumes for package %s: %s", err, pkg.Name, removeErr)
				}
			}
		}()
	}

	if err != nil {
		log.WriteTo(c.ui)
		return fmt.Errorf("Error compiling package %s: %s", pkg.Name, err.Error())
	}

	if exitCode != 0 {
		log.WriteTo(c.ui)
		return fmt.Errorf("Error - compilation for package %s exited with code %d", pkg.Name, exitCode)
	}

	return os.Rename(
		pkg.GetPackageCompiledTempDir(c.hostWorkDir),
		pkg.GetPackageCompiledDir(c.hostWorkDir))
}