forked from rancher/convoy
/
main.go
164 lines (145 loc) · 3.41 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
package main
import (
"fmt"
"github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/gorilla/mux"
"github.com/rancherio/rancher-volume/api"
"github.com/rancherio/rancher-volume/drivers"
"net"
"net/http"
"os"
"sync"
"time"
)
const (
VERSION = "0.1.5"
API_VERSION = "1"
LOCKFILE = "lock"
CONFIGFILE = "rancher-volume.cfg"
KEY_VOLUME = "volume-uuid"
KEY_SNAPSHOT = "snapshot-uuid"
KEY_OBJECTSTORE = "objectstore-uuid"
KEY_IMAGE = "image-uuid"
KEY_VOLUME_NAME = "volume-name"
VOLUME_CFG_PREFIX = "volume_"
CFG_POSTFIX = ".json"
)
type Volume struct {
UUID string
Name string
Base string
Size int64
MountPoint string
FileSystem string
Snapshots map[string]bool
}
type Server struct {
Router *mux.Router
StorageDriver drivers.Driver
GlobalLock *sync.RWMutex
NameVolumeMap map[string]string
Config
}
type Config struct {
Root string
Driver string
ImagesDir string
MountsDir string
DefaultVolumeSize int64
}
var (
lock string
logFile *os.File
log = logrus.WithFields(logrus.Fields{"pkg": "main"})
sockFile string = "/var/run/rancher/volume.sock"
client Client
)
type Client struct {
addr string
scheme string
transport *http.Transport
}
func cleanup() {
if r := recover(); r != nil {
api.ResponseLogAndError(r)
os.Exit(1)
}
}
func main() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(os.Stderr)
app := cli.NewApp()
app.Name = "rancher-volume"
app.Version = VERSION
app.Usage = "A volume manager capable of snapshot and delta backup"
app.CommandNotFound = cmdNotFound
serverCmd := cli.Command{
Name: "server",
Usage: "start rancher-volume server",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "debug",
Usage: "Enable debug log.",
},
cli.StringFlag{
Name: "log",
Usage: "specific output log file, otherwise output to stderr by default",
},
cli.StringFlag{
Name: "root",
Value: "/var/lib/rancher-volume",
Usage: "specific root directory of rancher-volume, if configure file exists, daemon specific options would be ignored",
},
cli.StringFlag{
Name: "driver",
Value: "devicemapper",
Usage: "Driver for volume manager, only support \"devicemapper\" currently",
},
cli.StringSliceFlag{
Name: "driver-opts",
Value: &cli.StringSlice{},
Usage: "options for driver",
},
cli.StringFlag{
Name: "images-dir",
Value: "/opt/rancher-volume_images",
Usage: "specific local directory would contains base images",
},
cli.StringFlag{
Name: "mounts-dir",
Value: "/var/lib/rancher-volume/mounts",
Usage: "default directory for mounting volume",
},
cli.StringFlag{
Name: "default-volume-size",
Value: "10G",
Usage: "default size for volume creation",
},
},
Action: cmdStartServer,
}
app.Commands = []cli.Command{
serverCmd,
infoCmd,
volumeCmd,
snapshotCmd,
objectstoreCmd,
}
client.addr = sockFile
client.scheme = "http"
client.transport = &http.Transport{
DisableCompression: true,
Dial: func(_, _ string) (net.Conn, error) {
return net.DialTimeout("unix", sockFile, 10*time.Second)
},
}
defer cleanup()
err := app.Run(os.Args)
if err != nil {
panic(fmt.Errorf("Error when executing command", err.Error()))
}
}
func cmdNotFound(c *cli.Context, command string) {
panic(fmt.Errorf("Unrecognized command", command))
}