/
fiddler.go
128 lines (110 loc) · 3.28 KB
/
fiddler.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
package main
import (
"github.com/hayesgm/fiddler/config"
"github.com/hayesgm/fiddler/tracker"
"github.com/hayesgm/fiddler/installer"
"github.com/hayesgm/fiddler/launcher"
"github.com/hayesgm/fiddler/spawner"
"github.com/coreos/go-etcd/etcd"
"github.com/go-contrib/uuid"
"log"
"flag"
"os/exec"
"fmt"
)
/*
Fiddler is a daemon that will check stats amoungst a
set of nodes in an etcd cluster. If certain thresholds
are exceeded across the stack, fiddle will issue
auto-scale commands to expand the cluster.
*/
/*
Fiddler knows how to spawn itself into CoreOS
and start docker containers. Thus, Fiddler is
quickly able to coordinate replicating itself
as load dictates. It's also able to detect drops
in load, where it will kill excess servers.
*/
/*
Fiddler uses a Fidderfile for all configuration settings.
./fiddler -c fiddler.conf
*/
var cli = etcd.NewClient()
var myid = uuid.NewV1().String()
func printUsage() {
fmt.Println("Fiddler is an app to auto-scale containers.")
fmt.Println("")
fmt.Println("Usage:")
fmt.Println("fiddler --config=<conf> install")
fmt.Println("\tInstalls Fiddler into systemd")
fmt.Println("fiddler --config=<conf> launch")
fmt.Println("\tLaunches a new container within Fiddler")
fmt.Println("fiddler --config=<conf> spawn")
fmt.Println("\tSpawns a new fiddler environment in the cloud")
fmt.Println("fiddler --config=<conf> daemon")
fmt.Println("\tRuns Fiddler like a daemon to monitor machine")
}
func main() {
// First, let's make sure we have a configuration file
var c = flag.String("config", "", "location of configuration file (http okay)")
flag.Parse()
if len(flag.Args()) < 1 {
printUsage()
return
}
if *c == "" {
fmt.Println("Missing config option")
printUsage()
return
}
// Next, we'll load the config
var conf *config.FiddlerConf
conf, err := config.LoadFiddlerConfig(*c)
if err != nil {
log.Fatal("Unable to load config file:", err)
}
var cmd = flag.Args()[0]
switch cmd {
case "i", "install":
// We should install Fiddler
err := installer.InstallFiddler(*c, *conf)
if err != nil {
log.Fatal("Error installing Fiddler:", err)
}
case "s", "spawn":
if len(conf.Env) == 0 {
fmt.Println("Must provide env name in config")
return
}
// We'll grab spawn pool and grow it
pool, err := spawner.GetSpawnPool(conf.Env)
if err != nil {
log.Fatal("Error getting spawn pool:", err)
}
err = pool.Grow(*c)
if err != nil {
log.Fatal("Error growing spawn pool:", err)
}
case "l", "launch":
// We should launch our container
var cmd *exec.Cmd
cmd, err = launcher.Launch(conf.Docker)
if err != nil {
log.Fatal("Error launching container:",conf.Docker,err)
}
err = cmd.Wait() // We'll stay open so long as the docker is open. We can ensure the docker stays open, etc.
if err != nil {
log.Fatal("Failed to run container:",conf.Docker,err)
}
case "d", "daemon":
// We should be like a daemon, tracking stats
// Now, we're going to make sure we're monitoring our stats
go tracker.TrackMyStats(cli, myid, []string{"cpu"})
go tracker.WatchStats(cli, myid, conf)
ch := make(chan int)
<- ch // Hold forever
default:
printUsage()
return
}
}