forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
178 lines (154 loc) · 4.62 KB
/
main.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package main
import (
"bytes"
"errors"
"flag"
"fmt"
"log"
"os"
"os/exec"
"strings"
)
var buildTargets = []string{"build"}
var categories = []string{
"aggregators",
"inputs",
"outputs",
"parsers",
"processors",
"secretstores",
"serializers",
}
const description = `
This is a tool build Telegraf with a custom set of plugins. The plugins are
select according to the specified Telegraf configuration files. This allows
to shrink the binary size by only selecting the plugins you really need.
A more detailed documentation is available at
http://github.com/influxdata/telegraf/tools/custom_builder/README.md
`
const examples = `
The following command with customize Telegraf to fit the configuration found
at the default locations
custom_builder --config /etc/telegraf/telegraf.conf --config-dir /etc/telegraf/telegraf.d
You can the --config and --config-dir multiple times
custom_builder --config global.conf --config myinputs.conf --config myoutputs.conf
or use one or more remote address(es) to load the config
custom_builder --config global.conf --config http://myserver/plugins.conf
Combinations of local and remote config as well as config directories are
possible.
`
func usage() {
fmt.Fprint(flag.CommandLine.Output(), description)
fmt.Fprintln(flag.CommandLine.Output(), "")
fmt.Fprintln(flag.CommandLine.Output(), "Usage:")
fmt.Fprintln(flag.CommandLine.Output(), " custom_builder [flags]")
fmt.Fprintln(flag.CommandLine.Output(), "")
fmt.Fprintln(flag.CommandLine.Output(), "Flags:")
flag.PrintDefaults()
fmt.Fprintln(flag.CommandLine.Output(), "")
fmt.Fprintln(flag.CommandLine.Output(), "Examples:")
fmt.Fprint(flag.CommandLine.Output(), examples)
fmt.Fprintln(flag.CommandLine.Output(), "")
}
type cmdConfig struct {
dryrun bool
showtags bool
migrations bool
quiet bool
root string
configFiles []string
configDirs []string
}
func main() {
var cfg cmdConfig
flag.Func("config",
"Import plugins from configuration file (can be used multiple times)",
func(s string) error {
cfg.configFiles = append(cfg.configFiles, s)
return nil
},
)
flag.Func("config-dir",
"Import plugins from configs in the given directory (can be used multiple times)",
func(s string) error {
cfg.configDirs = append(cfg.configDirs, s)
return nil
},
)
flag.BoolVar(&cfg.dryrun, "dry-run", false, "Skip the actual building step")
flag.BoolVar(&cfg.quiet, "quiet", false, "Print fewer log messages")
flag.BoolVar(&cfg.migrations, "migrations", false, "Include configuration migrations")
flag.BoolVar(&cfg.showtags, "tags", false, "Show build-tags used")
flag.Usage = usage
flag.Parse()
tagset, err := process(&cfg)
if err != nil {
log.Fatalln(err)
}
if len(tagset) == 0 {
log.Fatalln("Nothing selected!")
}
tags := "custom,"
if cfg.migrations {
tags += "migrations,"
}
tags += strings.Join(tagset, ",")
if cfg.showtags {
fmt.Printf("Build tags: %s\n", tags)
}
if !cfg.dryrun {
// Perform the build
var out bytes.Buffer
makeCmd := exec.Command("make", buildTargets...)
makeCmd.Env = append(os.Environ(), "BUILDTAGS="+tags)
makeCmd.Stdout = &out
makeCmd.Stderr = &out
if !cfg.quiet {
log.Println("Running build...")
}
if err := makeCmd.Run(); err != nil {
fmt.Println(out.String())
log.Fatalf("Running make failed: %v", err)
}
if !cfg.quiet {
fmt.Println(out.String())
}
} else if !cfg.quiet {
log.Println("DRY-RUN: Skipping build.")
}
}
func process(cmdcfg *cmdConfig) ([]string, error) {
// Check configuration options
if len(cmdcfg.configFiles) == 0 && len(cmdcfg.configDirs) == 0 {
return nil, errors.New("no configuration specified")
}
// Collect all available plugins
packages := packageCollection{root: cmdcfg.root}
if err := packages.CollectAvailable(); err != nil {
return nil, fmt.Errorf("collecting plugins failed: %w", err)
}
// Import the plugin list from Telegraf configuration files
log.Println("Importing configuration file(s)...")
cfg, nfiles, err := ImportConfigurations(cmdcfg.configFiles, cmdcfg.configDirs)
if err != nil {
return nil, fmt.Errorf("importing configuration(s) failed: %w", err)
}
if !cmdcfg.quiet {
log.Printf("Found %d configuration files...", nfiles)
}
// Check if we do have a config
if nfiles == 0 {
return nil, errors.New("no configuration files loaded")
}
// Process the plugin list with the given config. This will
// only keep the plugins that adhere to the filtering criteria.
enabled, err := cfg.Filter(packages)
if err != nil {
return nil, fmt.Errorf("filtering packages failed: %w", err)
}
if !cmdcfg.quiet {
enabled.Print()
}
// Extract the build-tags
return enabled.ExtractTags(), nil
}