Skip to content

Commit e9f2fa5

Browse files
committed
Examples of faulty entire file duplication issue in Go
1 parent e7e806d commit e9f2fa5

File tree

2 files changed

+535
-0
lines changed

2 files changed

+535
-0
lines changed

spec/fixtures/issue_6609_1.go

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
fmtlog "log"
6+
"net/http"
7+
"os"
8+
"path/filepath"
9+
"reflect"
10+
"strings"
11+
"time"
12+
13+
"github.com/Sirupsen/logrus"
14+
"github.com/cenk/backoff"
15+
"github.com/containous/flaeg"
16+
"github.com/containous/staert"
17+
"github.com/containous/traefik/acme"
18+
"github.com/containous/traefik/collector"
19+
"github.com/containous/traefik/configuration"
20+
"github.com/containous/traefik/job"
21+
"github.com/containous/traefik/log"
22+
"github.com/containous/traefik/provider/ecs"
23+
"github.com/containous/traefik/provider/kubernetes"
24+
"github.com/containous/traefik/safe"
25+
"github.com/containous/traefik/server"
26+
"github.com/containous/traefik/server/uuid"
27+
traefikTls "github.com/containous/traefik/tls"
28+
"github.com/containous/traefik/types"
29+
"github.com/containous/traefik/version"
30+
"github.com/coreos/go-systemd/daemon"
31+
)
32+
33+
func main() {
34+
//traefik config inits
35+
traefikConfiguration := NewTraefikConfiguration()
36+
traefikPointersConfiguration := NewTraefikDefaultPointersConfiguration()
37+
//traefik Command init
38+
traefikCmd := &flaeg.Command{
39+
Name: "traefik",
40+
Description: `traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease.
41+
Complete documentation is available at https://traefik.io`,
42+
Config: traefikConfiguration,
43+
DefaultPointersConfig: traefikPointersConfiguration,
44+
Run: func() error {
45+
run(&traefikConfiguration.GlobalConfiguration, traefikConfiguration.ConfigFile)
46+
return nil
47+
},
48+
}
49+
50+
//storeconfig Command init
51+
storeConfigCmd := newStoreConfigCmd(traefikConfiguration, traefikPointersConfiguration)
52+
53+
//init flaeg source
54+
f := flaeg.New(traefikCmd, os.Args[1:])
55+
//add custom parsers
56+
f.AddParser(reflect.TypeOf(configuration.EntryPoints{}), &configuration.EntryPoints{})
57+
f.AddParser(reflect.TypeOf(configuration.DefaultEntryPoints{}), &configuration.DefaultEntryPoints{})
58+
f.AddParser(reflect.TypeOf(traefikTls.RootCAs{}), &traefikTls.RootCAs{})
59+
f.AddParser(reflect.TypeOf(types.Constraints{}), &types.Constraints{})
60+
f.AddParser(reflect.TypeOf(kubernetes.Namespaces{}), &kubernetes.Namespaces{})
61+
f.AddParser(reflect.TypeOf(ecs.Clusters{}), &ecs.Clusters{})
62+
f.AddParser(reflect.TypeOf([]acme.Domain{}), &acme.Domains{})
63+
f.AddParser(reflect.TypeOf(types.Buckets{}), &types.Buckets{})
64+
65+
//add commands
66+
f.AddCommand(newVersionCmd())
67+
f.AddCommand(newBugCmd(traefikConfiguration, traefikPointersConfiguration))
68+
f.AddCommand(storeConfigCmd)
69+
f.AddCommand(newHealthCheckCmd(traefikConfiguration, traefikPointersConfiguration))
70+
71+
usedCmd, err := f.GetCommand()
72+
if err != nil {
73+
fmtlog.Println(err)
74+
os.Exit(-1)
75+
}
76+
77+
if _, err := f.Parse(usedCmd); err != nil {
78+
fmtlog.Printf("Error parsing command: %s\n", err)
79+
os.Exit(-1)
80+
}
81+
82+
//staert init
83+
s := staert.NewStaert(traefikCmd)
84+
//init toml source
85+
toml := staert.NewTomlSource("traefik", []string{traefikConfiguration.ConfigFile, "/etc/traefik/", "$HOME/.traefik/", "."})
86+
87+
//add sources to staert
88+
s.AddSource(toml)
89+
s.AddSource(f)
90+
if _, err := s.LoadConfig(); err != nil {
91+
fmtlog.Printf("Error reading TOML config file %s : %s\n", toml.ConfigFileUsed(), err)
92+
os.Exit(-1)
93+
}
94+
95+
traefikConfiguration.ConfigFile = toml.ConfigFileUsed()
96+
97+
kv, err := createKvSource(traefikConfiguration)
98+
if err != nil {
99+
fmtlog.Printf("Error creating kv store: %s\n", err)
100+
os.Exit(-1)
101+
}
102+
storeConfigCmd.Run = runStoreConfig(kv, traefikConfiguration)
103+
104+
// IF a KV Store is enable and no sub-command called in args
105+
if kv != nil && usedCmd == traefikCmd {
106+
if traefikConfiguration.Cluster == nil {
107+
traefikConfiguration.Cluster = &types.Cluster{Node: uuid.Get()}
108+
}
109+
if traefikConfiguration.Cluster.Store == nil {
110+
traefikConfiguration.Cluster.Store = &types.Store{Prefix: kv.Prefix, Store: kv.Store}
111+
}
112+
s.AddSource(kv)
113+
operation := func() error {
114+
_, err := s.LoadConfig()
115+
return err
116+
}
117+
notify := func(err error, time time.Duration) {
118+
log.Errorf("Load config error: %+v, retrying in %s", err, time)
119+
}
120+
err := backoff.RetryNotify(safe.OperationWithRecover(operation), job.NewBackOff(backoff.NewExponentialBackOff()), notify)
121+
if err != nil {
122+
fmtlog.Printf("Error loading configuration: %s\n", err)
123+
os.Exit(-1)
124+
}
125+
}
126+
127+
if err := s.Run(); err != nil {
128+
fmtlog.Printf("Error running traefik: %s\n", err)
129+
os.Exit(-1)
130+
}
131+
132+
os.Exit(0)
133+
}
134+
135+
func run(globalConfiguration *configuration.GlobalConfiguration, configFile string) {
136+
configureLogging(globalConfiguration)
137+
138+
if len(configFile) > 0 {
139+
log.Infof("Using TOML configuration file %s", configFile)
140+
}
141+
142+
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
143+
144+
globalConfiguration.SetEffectiveConfiguration(configFile)
145+
146+
jsonConf, _ := json.Marshal(globalConfiguration)
147+
log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
148+
149+
if globalConfiguration.CheckNewVersion {
150+
checkNewVersion()
151+
}
152+
153+
stats(globalConfiguration)
154+
155+
log.Debugf("Global configuration loaded %s", string(jsonConf))
156+
svr := server.NewServer(*globalConfiguration)
157+
svr.Start()
158+
defer svr.Close()
159+
160+
sent, err := daemon.SdNotify(false, "READY=1")
161+
if !sent && err != nil {
162+
log.Error("Fail to notify", err)
163+
}
164+
165+
t, err := daemon.SdWatchdogEnabled(false)
166+
if err != nil {
167+
log.Error("Problem with watchdog", err)
168+
} else if t != 0 {
169+
// Send a ping each half time given
170+
t = t / 2
171+
log.Info("Watchdog activated with timer each ", t)
172+
safe.Go(func() {
173+
tick := time.Tick(t)
174+
for range tick {
175+
_, errHealthCheck := healthCheck(*globalConfiguration)
176+
if globalConfiguration.Ping == nil || errHealthCheck == nil {
177+
if ok, _ := daemon.SdNotify(false, "WATCHDOG=1"); !ok {
178+
log.Error("Fail to tick watchdog")
179+
}
180+
} else {
181+
log.Error(errHealthCheck)
182+
}
183+
}
184+
})
185+
}
186+
187+
svr.Wait()
188+
log.Info("Shutting down")
189+
logrus.Exit(0)
190+
}
191+
192+
func configureLogging(globalConfiguration *configuration.GlobalConfiguration) {
193+
// configure default log flags
194+
fmtlog.SetFlags(fmtlog.Lshortfile | fmtlog.LstdFlags)
195+
196+
if globalConfiguration.Debug {
197+
globalConfiguration.LogLevel = "DEBUG"
198+
}
199+
200+
// configure log level
201+
level, err := logrus.ParseLevel(strings.ToLower(globalConfiguration.LogLevel))
202+
if err != nil {
203+
log.Error("Error getting level", err)
204+
}
205+
log.SetLevel(level)
206+
207+
// configure log output file
208+
logFile := globalConfiguration.TraefikLogsFile
209+
if len(logFile) > 0 {
210+
log.Warn("top-level traefikLogsFile has been deprecated -- please use traefiklog.filepath")
211+
}
212+
if globalConfiguration.TraefikLog != nil && len(globalConfiguration.TraefikLog.FilePath) > 0 {
213+
logFile = globalConfiguration.TraefikLog.FilePath
214+
}
215+
216+
// configure log format
217+
var formatter logrus.Formatter
218+
if globalConfiguration.TraefikLog != nil && globalConfiguration.TraefikLog.Format == "json" {
219+
formatter = &logrus.JSONFormatter{}
220+
} else {
221+
disableColors := false
222+
if len(logFile) > 0 {
223+
disableColors = true
224+
}
225+
formatter = &logrus.TextFormatter{DisableColors: disableColors, FullTimestamp: true, DisableSorting: true}
226+
}
227+
log.SetFormatter(formatter)
228+
229+
if len(logFile) > 0 {
230+
dir := filepath.Dir(logFile)
231+
232+
err := os.MkdirAll(dir, 0755)
233+
if err != nil {
234+
log.Errorf("Failed to create log path %s: %s", dir, err)
235+
}
236+
237+
err = log.OpenFile(logFile)
238+
logrus.RegisterExitHandler(func() {
239+
if err := log.CloseFile(); err != nil {
240+
log.Error("Error closing log", err)
241+
}
242+
})
243+
if err != nil {
244+
log.Error("Error opening file", err)
245+
}
246+
}
247+
}
248+
249+
func checkNewVersion() {
250+
ticker := time.Tick(24 * time.Hour)
251+
safe.Go(func() {
252+
for time.Sleep(10 * time.Minute); ; <-ticker {
253+
version.CheckNewVersion()
254+
}
255+
})
256+
}
257+
258+
func stats(globalConfiguration *configuration.GlobalConfiguration) {
259+
if globalConfiguration.SendAnonymousUsage {
260+
log.Info(`
261+
Stats collection is enabled.
262+
Many thanks for contributing to Traefik's improvement by allowing us to receive anonymous information from your configuration.
263+
Help us improve Traefik by leaving this feature on :)
264+
More details on: https://docs.traefik.io/basic/#collected-data
265+
`)
266+
collect(globalConfiguration)
267+
} else {
268+
log.Info(`
269+
Stats collection is disabled.
270+
Help us improve Traefik by turning this feature on :)
271+
More details on: https://docs.traefik.io/basic/#collected-data
272+
`)
273+
}
274+
}
275+
276+
func collect(globalConfiguration *configuration.GlobalConfiguration) {
277+
ticker := time.Tick(24 * time.Hour)
278+
safe.Go(func() {
279+
for time.Sleep(10 * time.Minute); ; <-ticker {
280+
if err := collector.Collect(globalConfiguration); err != nil {
281+
log.Debug(err)
282+
}
283+
}
284+
})
285+
}

0 commit comments

Comments
 (0)