-
Notifications
You must be signed in to change notification settings - Fork 69
/
bundler.go
110 lines (90 loc) · 2.98 KB
/
bundler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package recipes
import (
"context"
log "github.com/sirupsen/logrus"
"github.com/newrelic/newrelic-cli/internal/install/types"
)
var coreRecipeMap = map[string]bool{
types.InfraAgentRecipeName: true,
types.LoggingRecipeName: true,
}
type Bundler struct {
AvailableRecipes RecipeDetectionResults
Context context.Context
cachedBundleRecipes map[string]*BundleRecipe
}
func NewBundler(context context.Context, availableRecipes RecipeDetectionResults) *Bundler {
return &Bundler{
Context: context,
AvailableRecipes: availableRecipes,
cachedBundleRecipes: make(map[string]*BundleRecipe),
}
}
func (b *Bundler) CreateCoreBundle() *Bundle {
return b.createBundle(b.getCoreRecipeNames(), BundleTypes.CORE)
}
func (b *Bundler) CreateAdditionalGuidedBundle() *Bundle {
var recipes []string
for _, d := range b.AvailableRecipes {
if !coreRecipeMap[d.Recipe.Name] {
recipes = append(recipes, d.Recipe.Name)
}
}
return b.createBundle(recipes, BundleTypes.ADDITIONALGUIDED)
}
func (b *Bundler) CreateAdditionalTargetedBundle(recipes []string) *Bundle {
return b.createBundle(recipes, BundleTypes.ADDITIONALTARGETED)
}
func (b *Bundler) getCoreRecipeNames() []string {
coreRecipeNames := make([]string, 0, len(coreRecipeMap))
for k := range coreRecipeMap {
coreRecipeNames = append(coreRecipeNames, k)
}
return coreRecipeNames
}
func (b *Bundler) createBundle(recipes []string, bType BundleType) *Bundle {
bundle := &Bundle{Type: bType}
for _, r := range recipes {
if d, ok := b.AvailableRecipes.GetRecipeDetection(r); ok {
bundleRecipe := b.getBundleRecipeWithDependencies(d.Recipe)
if bundleRecipe != nil {
log.Debugf("Adding bundle recipe:%s status:%+v dependencies:%+v", bundleRecipe.Recipe.Name, bundleRecipe.DetectedStatuses, bundleRecipe.Recipe.Dependencies)
bundle.AddRecipe(bundleRecipe)
}
}
}
return bundle
}
func (b *Bundler) getBundleRecipeWithDependencies(recipe *types.OpenInstallationRecipe) *BundleRecipe {
if br, ok := b.cachedBundleRecipes[recipe.Name]; ok {
return br
}
bundleRecipe := &BundleRecipe{
Recipe: recipe,
}
for _, d := range recipe.Dependencies {
if dt, ok := b.AvailableRecipes.GetRecipeDetection(d); ok {
dr := b.getBundleRecipeWithDependencies(dt.Recipe)
if dr != nil {
bundleRecipe.Dependencies = append(bundleRecipe.Dependencies, dr)
continue
} else {
log.Debugf("dependent bundle recipe %s not found, skipping recipe %s", d, recipe.Name)
}
} else {
log.Debugf("dependent recipe %s not found, skipping recipe %s", d, recipe.Name)
}
// A dependency is missing, invalidating the bundle recipe
b.cachedBundleRecipes[recipe.Name] = nil
return nil
}
if bundleRecipe.AreAllDependenciesAvailable() {
if dt, ok := b.AvailableRecipes.GetRecipeDetection(recipe.Name); ok {
bundleRecipe.AddDetectionStatus(dt.Status, dt.DurationMs)
b.cachedBundleRecipes[recipe.Name] = bundleRecipe
return bundleRecipe
}
}
b.cachedBundleRecipes[recipe.Name] = nil
return nil
}