示例#1
0
// CreateBaseCompilationImage will recompile the base BOSH image for a release
func (f *Fissile) CreateBaseCompilationImage(baseImageName, repository, metricsPath string, keepContainer bool) error {
	if metricsPath != "" {
		stampy.Stamp(metricsPath, "fissile", "create-compilation-image", "start")
		defer stampy.Stamp(metricsPath, "fissile", "create-compilation-image", "done")
	}

	dockerManager, err := docker.NewImageManager()
	if err != nil {
		return fmt.Errorf("Error connecting to docker: %s", err.Error())
	}

	baseImage, err := dockerManager.FindImage(baseImageName)
	if err != nil {
		return fmt.Errorf("Error looking up base image %s: %s", baseImageName, err)
	}

	f.UI.Println(color.GreenString("Base image with ID %s found", color.YellowString(baseImage.ID)))

	comp, err := compilator.NewCompilator(dockerManager, "", "", repository, compilation.UbuntuBase, f.Version, keepContainer, f.UI)
	if err != nil {
		return fmt.Errorf("Error creating a new compilator: %s", err.Error())
	}

	if _, err := comp.CreateCompilationBase(baseImageName); err != nil {
		return fmt.Errorf("Error creating compilation base image: %s", err.Error())
	}

	return nil
}
示例#2
0
func (j roleBuildJob) Run() {
	select {
	case <-j.abort:
		j.resultsCh <- nil
		return
	default:
	}

	roleImageName := GetRoleDevImageName(j.repository, j.role, j.role.GetRoleDevVersion())
	if !j.force {
		if hasImage, err := j.dockerManager.HasImage(roleImageName); err != nil {
			j.resultsCh <- err
			return
		} else if hasImage {
			j.ui.Printf("Skipping build of role image %s because it exists\n", color.YellowString(j.role.Name))
			j.resultsCh <- nil
			return
		}
	}

	if j.builder.metricsPath != "" {
		seriesName := fmt.Sprintf("create-role-images::%s", roleImageName)

		stampy.Stamp(j.builder.metricsPath, "fissile", seriesName, "start")
		defer stampy.Stamp(j.builder.metricsPath, "fissile", seriesName, "done")
	}

	j.ui.Printf("Creating Dockerfile for role %s ...\n", color.YellowString(j.role.Name))
	dockerfileDir, err := j.builder.CreateDockerfileDir(j.role, j.baseImageName)
	if err != nil {
		j.resultsCh <- fmt.Errorf("Error creating Dockerfile and/or assets for role %s: %s", j.role.Name, err.Error())
		return
	}

	if j.noBuild {
		j.ui.Printf("Skipping build of role image %s because of flag\n", color.YellowString(j.role.Name))
		j.resultsCh <- nil
		return
	}

	if !strings.HasSuffix(dockerfileDir, string(os.PathSeparator)) {
		dockerfileDir = fmt.Sprintf("%s%c", dockerfileDir, os.PathSeparator)
	}

	j.ui.Printf("Building docker image of %s in %s ...\n", color.YellowString(j.role.Name), color.YellowString(dockerfileDir))

	log := new(bytes.Buffer)
	stdoutWriter := docker.NewFormattingWriter(
		log,
		docker.ColoredBuildStringFunc(roleImageName),
	)

	err = j.dockerManager.BuildImage(dockerfileDir, roleImageName, stdoutWriter)
	if err != nil {
		log.WriteTo(j.ui)
		j.resultsCh <- fmt.Errorf("Error building image: %s", err.Error())
		return
	}
	j.resultsCh <- nil
}
示例#3
0
// GenerateBaseDockerImage generates a base docker image to be used as a FROM for role images
func (f *Fissile) GenerateBaseDockerImage(targetPath, baseImage, metricsPath string, noBuild bool, repository string) error {
	if metricsPath != "" {
		stampy.Stamp(metricsPath, "fissile", "create-role-base", "start")
		defer stampy.Stamp(metricsPath, "fissile", "create-role-base", "done")
	}

	dockerManager, err := docker.NewImageManager()
	if err != nil {
		return fmt.Errorf("Error connecting to docker: %s", err.Error())
	}

	baseImageName := builder.GetBaseImageName(repository, f.Version)

	image, err := dockerManager.FindImage(baseImageName)
	if err == docker.ErrImageNotFound {
		f.UI.Println("Image doesn't exist, it will be created ...")
	} else if err != nil {
		return fmt.Errorf("Error looking up image: %s", err.Error())
	} else {
		f.UI.Println(color.GreenString(
			"Base role image %s with ID %s already exists. Doing nothing.",
			color.YellowString(baseImageName),
			color.YellowString(image.ID),
		))
		return nil
	}

	if !strings.HasSuffix(targetPath, string(os.PathSeparator)) {
		targetPath = fmt.Sprintf("%s%c", targetPath, os.PathSeparator)
	}

	baseImageBuilder := builder.NewBaseImageBuilder(baseImage)

	if noBuild {
		f.UI.Println("Skipping image build because of flag.")
		return nil
	}

	f.UI.Println("Building base docker image ...")
	log := new(bytes.Buffer)
	stdoutWriter := docker.NewFormattingWriter(
		log,
		docker.ColoredBuildStringFunc(baseImageName),
	)

	tarPopulator := baseImageBuilder.NewDockerPopulator()
	err = dockerManager.BuildImageFromCallback(baseImageName, stdoutWriter, tarPopulator)
	if err != nil {
		log.WriteTo(f.UI)
		return fmt.Errorf("Error building base image: %s", err)
	}
	f.UI.Println(color.GreenString("Done."))

	return nil
}
示例#4
0
// GenerateRoleImages generates all role images using dev releases
func (f *Fissile) GenerateRoleImages(targetPath, repository, metricsPath string, noBuild, force bool, workerCount int, rolesManifestPath, compiledPackagesPath, lightManifestPath, darkManifestPath string) error {
	if len(f.releases) == 0 {
		return fmt.Errorf("Releases not loaded")
	}

	if metricsPath != "" {
		stampy.Stamp(metricsPath, "fissile", "create-role-images", "start")
		defer stampy.Stamp(metricsPath, "fissile", "create-role-images", "done")
	}

	roleManifest, err := model.LoadRoleManifest(rolesManifestPath, f.releases)
	if err != nil {
		return fmt.Errorf("Error loading roles manifest: %s", err.Error())
	}

	packagesImageBuilder, err := builder.NewPackagesImageBuilder(
		repository,
		compiledPackagesPath,
		targetPath,
		f.Version,
		f.UI,
	)
	if err != nil {
		return err
	}

	err = f.GeneratePackagesRoleImage(repository, roleManifest, noBuild, force, packagesImageBuilder)
	if err != nil {
		return err
	}

	packagesLayerImageName := packagesImageBuilder.GetRolePackageImageName(roleManifest)

	roleBuilder, err := builder.NewRoleImageBuilder(
		repository,
		compiledPackagesPath,
		targetPath,
		lightManifestPath,
		darkManifestPath,
		metricsPath,
		"",
		f.Version,
		f.UI,
	)
	if err != nil {
		return err
	}

	if err := roleBuilder.BuildRoleImages(roleManifest.Roles, repository, packagesLayerImageName, force, noBuild, workerCount); err != nil {
		return err
	}

	return nil
}
示例#5
0
// Compile will compile a list of dev BOSH releases
func (f *Fissile) Compile(repository, targetPath, roleManifestPath, metricsPath string, workerCount int) error {
	if len(f.releases) == 0 {
		return fmt.Errorf("Releases not loaded")
	}

	if metricsPath != "" {
		stampy.Stamp(metricsPath, "fissile", "compile-packages", "start")
		defer stampy.Stamp(metricsPath, "fissile", "compile-packages", "done")
	}

	dockerManager, err := docker.NewImageManager()
	if err != nil {
		return fmt.Errorf("Error connecting to docker: %s", err.Error())
	}

	roleManifest, err := model.LoadRoleManifest(roleManifestPath, f.releases)
	if err != nil {
		return fmt.Errorf("Error loading roles manifest: %s", err.Error())
	}

	f.UI.Println(color.GreenString("Compiling packages for dev releases:"))
	for _, release := range f.releases {
		f.UI.Printf("         %s (%s)\n", color.YellowString(release.Name), color.MagentaString(release.Version))
	}

	comp, err := compilator.NewCompilator(dockerManager, targetPath, metricsPath, repository, compilation.UbuntuBase, f.Version, false, f.UI)
	if err != nil {
		return fmt.Errorf("Error creating a new compilator: %s", err.Error())
	}

	if err := comp.Compile(workerCount, f.releases, roleManifest); err != nil {
		return fmt.Errorf("Error compiling packages: %s", err.Error())
	}

	return nil
}
示例#6
0
func (j compileJob) Run() {
	c := j.compilator

	// Metrics: Overall time for the specific job
	var waitSeriesName string
	var runSeriesName string
	if c.metricsPath != "" {
		seriesName := fmt.Sprintf("compile-packages::%s/%s", j.pkg.Release.Name, j.pkg.Name)
		waitSeriesName = fmt.Sprintf("compile-packages::wait::%s/%s", j.pkg.Release.Name, j.pkg.Name)
		runSeriesName = fmt.Sprintf("compile-packages::run::%s/%s", j.pkg.Release.Name, j.pkg.Name)

		stampy.Stamp(c.metricsPath, "fissile", seriesName, "start")
		defer stampy.Stamp(c.metricsPath, "fissile", seriesName, "done")

		stampy.Stamp(c.metricsPath, "fissile", waitSeriesName, "start")
	}

	// (xx) Wait for our deps. Note how without deps the killCh is
	// not checked and ignored. It is also in a race with (**)
	// draining doneCh and actually signaling the kill.

	// Time spent waiting
	for _, dep := range j.pkg.Dependencies {
		done := false
		for !done {
			select {
			case <-j.killCh:
				c.ui.Printf("killed:  %s/%s\n",
					color.MagentaString(j.pkg.Release.Name),
					color.MagentaString(j.pkg.Name))
				j.doneCh <- compileResult{pkg: j.pkg, err: errWorkerAbort}

				if c.metricsPath != "" {
					stampy.Stamp(c.metricsPath, "fissile", waitSeriesName, "done")
				}
				return
			case <-time.After(5 * time.Second):
				c.ui.Printf("waiting: %s/%s - %s\n",
					color.MagentaString(j.pkg.Release.Name),
					color.MagentaString(j.pkg.Name),
					color.MagentaString(dep.Name))
			case <-c.signalDependencies[dep.Fingerprint]:
				c.ui.Printf("depdone: %s/%s - %s\n",
					color.MagentaString(j.pkg.Release.Name),
					color.MagentaString(j.pkg.Name),
					color.MagentaString(dep.Name))
				done = true
			}
		}
	}

	if c.metricsPath != "" {
		stampy.Stamp(c.metricsPath, "fissile", waitSeriesName, "done")
	}

	c.ui.Printf("compile: %s/%s\n",
		color.MagentaString(j.pkg.Release.Name),
		color.MagentaString(j.pkg.Name))

	// Time spent in actual compilation
	if c.metricsPath != "" {
		stampy.Stamp(c.metricsPath, "fissile", runSeriesName, "start")
	}

	workerErr := compilePackageHarness(c, j.pkg)

	if c.metricsPath != "" {
		stampy.Stamp(c.metricsPath, "fissile", runSeriesName, "done")
	}

	c.ui.Printf("done:    %s/%s\n",
		color.MagentaString(j.pkg.Release.Name),
		color.MagentaString(j.pkg.Name))

	j.doneCh <- compileResult{pkg: j.pkg, err: workerErr}
}