-
Notifications
You must be signed in to change notification settings - Fork 278
/
builder.go
158 lines (126 loc) Β· 5 KB
/
builder.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package executables
import (
"context"
"fmt"
"os"
"strings"
"github.com/aws/eks-anywhere/pkg/filewriter"
"github.com/aws/eks-anywhere/pkg/logger"
"github.com/aws/eks-anywhere/pkg/providers/cloudstack/decoder"
)
const defaultEksaImage = "public.ecr.aws/l0g8r8j6/eks-anywhere-cli-tools:v0.7.2-eks-a-v0.0.0-dev-build.1864"
type ExecutableBuilder interface {
Init(ctx context.Context) (Closer, error)
Build(binaryPath string) Executable
}
type ExecutablesBuilder struct {
executableBuilder ExecutableBuilder
}
func NewExecutablesBuilder(executableBuilder ExecutableBuilder) *ExecutablesBuilder {
return &ExecutablesBuilder{
executableBuilder: executableBuilder,
}
}
func (b *ExecutablesBuilder) BuildKindExecutable(writer filewriter.FileWriter) *Kind {
return NewKind(b.executableBuilder.Build(kindPath), writer)
}
func (b *ExecutablesBuilder) BuildClusterAwsAdmExecutable() *Clusterawsadm {
return NewClusterawsadm(b.executableBuilder.Build(clusterAwsAdminPath))
}
func (b *ExecutablesBuilder) BuildClusterCtlExecutable(writer filewriter.FileWriter) *Clusterctl {
return NewClusterctl(b.executableBuilder.Build(clusterCtlPath), writer)
}
func (b *ExecutablesBuilder) BuildKubectlExecutable() *Kubectl {
return NewKubectl(b.executableBuilder.Build(kubectlPath))
}
func (b *ExecutablesBuilder) BuildGovcExecutable(writer filewriter.FileWriter, opts ...GovcOpt) *Govc {
return NewGovc(b.executableBuilder.Build(govcPath), writer, opts...)
}
// BuildCmkExecutable initializes a Cmk object and returns it.
func (b *ExecutablesBuilder) BuildCmkExecutable(writer filewriter.FileWriter, config *decoder.CloudStackExecConfig) (*Cmk, error) {
return NewCmk(b.executableBuilder.Build(cmkPath), writer, config)
}
func (b *ExecutablesBuilder) BuildAwsCli() *AwsCli {
return NewAwsCli(b.executableBuilder.Build(awsCliPath))
}
func (b *ExecutablesBuilder) BuildFluxExecutable() *Flux {
return NewFlux(b.executableBuilder.Build(fluxPath))
}
func (b *ExecutablesBuilder) BuildTroubleshootExecutable() *Troubleshoot {
return NewTroubleshoot(b.executableBuilder.Build(troubleshootPath))
}
func (b *ExecutablesBuilder) BuildHelmExecutable(opts ...HelmOpt) *Helm {
return NewHelm(b.executableBuilder.Build(helmPath), opts...)
}
// BuildDockerExecutable initializes a docker executable and returns it.
func (b *ExecutablesBuilder) BuildDockerExecutable() *Docker {
return NewDocker(b.executableBuilder.Build(dockerPath))
}
// Init initializes the executable builder and returns a Closer
// that needs to be called once the executables are not in used anymore
// The closer will cleanup and free all internal resources.
func (b *ExecutablesBuilder) Init(ctx context.Context) (Closer, error) {
return b.executableBuilder.Init(ctx)
}
func BuildSonobuoyExecutable() *Sonobuoy {
return NewSonobuoy(&executable{
cli: sonobuoyPath,
})
}
func BuildDockerExecutable() *Docker {
return NewDocker(&executable{
cli: dockerPath,
})
}
// RunExecutablesInDocker determines if binary executables should be ran
// from a docker container or native binaries from the host path
// It reads MR_TOOLS_DISABLE variable.
func ExecutablesInDocker() bool {
if env, ok := os.LookupEnv("MR_TOOLS_DISABLE"); ok && strings.EqualFold(env, "true") {
logger.Info("Warning: eks-a tools image disabled, using client's executables")
return false
}
return true
}
// InitInDockerExecutablesBuilder builds and inits a default ExecutablesBuilder to run executables in a docker container
// that will make use of a long running docker container.
func InitInDockerExecutablesBuilder(ctx context.Context, image string, mountDirs ...string) (*ExecutablesBuilder, Closer, error) {
b, err := NewInDockerExecutablesBuilder(BuildDockerExecutable(), image, mountDirs...)
if err != nil {
return nil, nil, err
}
closer, err := b.Init(ctx)
if err != nil {
return nil, nil, err
}
return b, closer, nil
}
// NewInDockerExecutablesBuilder builds an executables builder for docker.
func NewInDockerExecutablesBuilder(dockerClient DockerClient, image string, mountDirs ...string) (*ExecutablesBuilder, error) {
currentDir, err := os.Getwd()
if err != nil {
return nil, fmt.Errorf("getting current directory: %v", err)
}
mountDirs = append(mountDirs, currentDir)
dockerContainer := newDockerContainer(image, currentDir, mountDirs, dockerClient)
dockerExecutableBuilder := NewDockerExecutableBuilder(dockerContainer)
return NewExecutablesBuilder(dockerExecutableBuilder), nil
}
func NewLocalExecutablesBuilder() *ExecutablesBuilder {
return NewExecutablesBuilder(newLocalExecutableBuilder())
}
func DefaultEksaImage() string {
return defaultEksaImage
}
type Closer func(ctx context.Context) error
// Close implements interface types.Closer.
func (c Closer) Close(ctx context.Context) error {
return c(ctx)
}
// CheckErr just calls the closer and logs an error if present
// It's mostly a helper for defering the close in a oneliner without ignoring the error.
func (c Closer) CheckErr(ctx context.Context) {
if err := c(ctx); err != nil {
logger.Error(err, "Failed closing container for executables")
}
}