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
}