func()

in pkg/testing/fixture.go [1004:1108]


func (f *Fixture) prepareComponents(workDir string, components ...UsableComponent) error {
	if len(components) == 0 {
		f.t.Logf("Components were not modified from the fetched artifact")
		return nil
	}

	// determine the components to keep
	keep := make(map[string]bool)
	for _, comp := range components {
		if comp.BinaryPath == "" {
			keep[comp.Name] = false
		}
	}

	// now remove all that should not be kept; removal is only
	// done by removing the spec file, no need to delete the binary
	componentsDir, err := FindComponentsDir(workDir, "")
	if err != nil {
		return err
	}
	contents, err := os.ReadDir(componentsDir)
	if err != nil {
		return fmt.Errorf("failed to read contents of components directory %s: %w", componentsDir, err)
	}
	var kept []string
	for _, fi := range contents {
		if fi.IsDir() {
			// ignore directories (only care about specification files)
			continue
		}
		name := fi.Name()
		if !strings.HasSuffix(name, ".spec.yml") {
			// ignore other files (only care about specification files)
			continue
		}
		name = strings.TrimSuffix(name, ".spec.yml")
		_, ok := keep[name]
		if !ok {
			// specification file is not marked to keep, so we remove it
			// so the Elastic Agent doesn't know how to run that component
			deleteFile := filepath.Join(componentsDir, fi.Name())
			if err := os.Remove(deleteFile); err != nil {
				return fmt.Errorf("failed to delete component specification %s: %w", deleteFile, err)
			}
		} else {
			kept = append(kept, name)
			keep[name] = true
		}
	}
	var missing []string
	for name, found := range keep {
		if !found {
			missing = append(missing, name)
		}
	}
	if len(missing) > 0 {
		return fmt.Errorf("failed to find defined usable components: %s", strings.Join(missing, ", "))
	}
	if len(kept) == 0 {
		f.t.Logf("All component specifications where removed")
	} else {
		f.t.Logf("All component specifications where removed except: %s", strings.Join(kept, ", "))
	}

	// place the components that should be set to be usable by the Elastic Agent
	var placed []string
	for _, comp := range components {
		if comp.BinaryPath == "" {
			continue
		}
		destBinary := filepath.Join(componentsDir, comp.Name)
		if f.operatingSystem == "windows" {
			destBinary += ".exe"
		}
		if err := copy.Copy(comp.BinaryPath, destBinary); err != nil {
			return fmt.Errorf("failed to copy %s to %s: %w", comp.BinaryPath, destBinary, err)
		}
		if runtime.GOOS != "windows" {
			// chown is not supported on Windows
			if err := os.Chown(destBinary, os.Geteuid(), os.Getgid()); err != nil {
				return fmt.Errorf("failed to chown %s: %w", destBinary, err)
			}
		}
		if err := os.Chmod(destBinary, 0755); err != nil {
			return fmt.Errorf("failed to chmod %s: %w", destBinary, err)
		}
		destSpec := filepath.Join(componentsDir, fmt.Sprintf("%s.spec.yml", comp.Name))
		if comp.SpecPath != "" {
			if err := copy.Copy(comp.SpecPath, destSpec); err != nil {
				return fmt.Errorf("failed to copy %s to %s: %w", comp.SpecPath, destSpec, err)
			}
		} else if comp.Spec != nil {
			if err := writeSpecFile(destSpec, comp.Spec); err != nil {
				return fmt.Errorf("failed to write specification file %s: %w", destSpec, err)
			}
		}
		placed = append(placed, comp.Name)

	}
	if len(placed) > 0 {
		f.t.Logf("Placed component specifications: %s", strings.Join(placed, ", "))
	}

	return nil
}