// Run is the function that starts the collector. The dryMode parameter // indicates whether the collector should loop forever or not. // // It assumes the configuration has already been defined (from a config file or // memory). func Run(dryMode bool) { log.Init() connString, err := config.GetString("database:url") if err != nil { connString = db.DefaultDatabaseURL } dbName, err := config.GetString("database:name") if err != nil { dbName = db.DefaultDatabaseName } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) if !dryMode { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Println("Warning: configuration didn't declare a provisioner, using default provisioner.") provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) timer, err := config.GetInt("colletor:ticker-time") if err != nil { timer = 60 } ticker := time.Tick(time.Duration(timer) * time.Second) fmt.Println("tsuru collector agent started...") collect(ticker) } }
func Run(flags map[string]interface{}) { configFile := loadConfig(flags) log.Init() dry, ok := flags["dry"].(bool) if !ok { dry = false } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) if !dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) ticker := time.Tick(time.Minute) fmt.Println("tsuru collector agent started...") collect(ticker) } }
func (r *NginxRouter) AddRoute(name, address string) error { domain, err := config.GetString("nginx:domain") if err != nil { return err } routesPath, err := config.GetString("nginx:routes-path") if err != nil { return err } file, err := filesystem().Create(routesPath + "/" + name) if err != nil { return err } defer file.Close() template := `server { listen 80; server_name %s.%s; location / { proxy_pass http://%s; } }` template = fmt.Sprintf(template, name, domain, address) data := []byte(template) _, err = file.Write(data) if err != nil { return err } return r.restart() }
func dockerCluster() *cluster.Cluster { cmutex.Lock() defer cmutex.Unlock() if dCluster == nil { if segregate, _ := config.GetBool("docker:segregate"); segregate { dCluster, _ = cluster.New(segScheduler) } else { clusterNodes = make(map[string]string) servers, _ := config.GetList("docker:servers") if len(servers) < 1 { log.Fatal(`Tsuru is misconfigured. Setting "docker:servers" is mandatory`) } nodes := make([]cluster.Node, len(servers)) for index, server := range servers { id := fmt.Sprintf("server%d", index) node := cluster.Node{ ID: id, Address: server, } nodes[index] = node clusterNodes[id] = server } dCluster, _ = cluster.New(nil, nodes...) } if redisServer, err := config.GetString("docker:scheduler:redis-server"); err == nil { prefix, _ := config.GetString("docker:scheduler:redis-prefix") if password, err := config.GetString("docker:scheduler:redis-password"); err == nil { dCluster.SetStorage(storage.AuthenticatedRedis(redisServer, password, prefix)) } else { dCluster.SetStorage(storage.Redis(redisServer, prefix)) } } } return dCluster }
func (redismqQFactory) get(name, consumerName string) (*redismqQ, error) { host, err := config.GetString("queue:redis-host") if err != nil { host = "localhost" } port, err := config.GetString("queue:redis-port") if err != nil { if nport, err := config.GetInt("queue:redis-port"); err != nil { port = "6379" } else { port = fmt.Sprintf("%d", nport) } } password, _ := config.GetString("queue:redis-password") db, err := config.GetInt("queue:redis-db") if err != nil { db = 3 } queue := redismq.CreateQueue(host, port, password, int64(db), name) consumer, err := queue.AddConsumer(consumerName) if err != nil { return nil, err } return &redismqQ{name: name, queue: queue, consumer: consumer}, nil }
// sshCmds returns the commands needed to start a ssh daemon. func sshCmds() ([]string, error) { addKeyCommand, err := config.GetString("docker:ssh:add-key-cmd") if err != nil { return nil, err } keyFile, err := config.GetString("docker:ssh:public-key") if err != nil { if u, err := user.Current(); err == nil { keyFile = path.Join(u.HomeDir, ".ssh", "id_rsa.pub") } else { keyFile = os.ExpandEnv("${HOME}/.ssh/id_rsa.pub") } } f, err := filesystem().Open(keyFile) if err != nil { return nil, err } defer f.Close() keyContent, err := ioutil.ReadAll(f) if err != nil { return nil, err } sshdPath, err := config.GetString("docker:ssh:sshd-path") if err != nil { sshdPath = "/usr/sbin/sshd" } return []string{ fmt.Sprintf("%s %s", addKeyCommand, bytes.TrimSpace(keyContent)), sshdPath + " -D", }, nil }
func runContainerCmd(app provision.App) ([]string, error) { docker, err := config.GetString("docker:binary") if err != nil { return []string{}, err } repoNamespace, err := config.GetString("docker:repository-namespace") if err != nil { return []string{}, err } runBin, err := config.GetString("docker:run-cmd:bin") if err != nil { return []string{}, err } runArgs, err := config.GetString("docker:run-cmd:args") if err != nil { return []string{}, err } port, err := config.GetString("docker:run-cmd:port") if err != nil { return []string{}, err } cmd := fmt.Sprintf("%s %s", runBin, runArgs) imageName := fmt.Sprintf("%s/%s", repoNamespace, app.GetName()) // TODO (flaviamissi): should be external function wholeCmd := []string{docker, "run", "-d", "-p", port, imageName, cmd} return wholeCmd, nil }
// RunAdminServer starts tsuru administrative api func RunAdminServer(dry bool) { log.Init() connString, err := config.GetString("database:url") if err != nil { connString = db.DefaultDatabaseURL } dbName, err := config.GetString("database:name") if err != nil { dbName = db.DefaultDatabaseName } fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString) if !dry { provisioner, err := getProvisioner() if err != nil { fmt.Printf("Warning: configuration didn't declare a provisioner, using default provisioner.\n") } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) listen, err := config.GetString("admin-listen") if err != nil { fatal(err) } listener, err := net.Listen("tcp", listen) if err != nil { fatal(err) } fmt.Printf("tsuru HTTP server listening at %s...\n", listen) http.Handle("/", m) fatal(http.Serve(listener, nil)) } }
func (s *S) TestGetServerUri(c *gocheck.C) { server, err := config.GetString("git:host") c.Assert(err, gocheck.IsNil) protocol, err := config.GetString("git:protocol") port, err := config.Get("git:port") uri := GitServerUri() c.Assert(uri, gocheck.Equals, fmt.Sprintf("%s://%s:%d", protocol, server, port)) }
func (s *S) TestGetServerUriWithoutPort(c *gocheck.C) { config.Unset("git:port") defer config.Set("git:port", 8080) server, err := config.GetString("git:host") c.Assert(err, gocheck.IsNil) protocol, err := config.GetString("git:protocol") uri := GitServerUri() c.Assert(uri, gocheck.Equals, fmt.Sprintf("%s://%s", protocol, server)) }
func main() { var ( configFile string dry bool ) logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags) if err != nil { stdlog.Fatal(err) } log.SetLogger(logger) flag.StringVar(&configFile, "config", "/etc/tsuru/tsuru.conf", "tsuru config file") flag.BoolVar(&dry, "dry", false, "dry-run: does not start the agent (for testing purposes)") flag.Parse() err = config.ReadConfigFile(configFile) if err != nil { fatal(err) } connString, err := config.GetString("database:url") if err != nil { fatal(err) } dbName, err := config.GetString("database:name") if err != nil { fatal(err) } db.Session, err = db.Open(connString, dbName) if err != nil { fatal(err) } defer db.Session.Close() fmt.Printf("Connected to MongoDB server at %s.\n", connString) fmt.Printf("Using the database %q.\n\n", dbName) if !dry { provisioner, err := config.GetString("provisioner") if err != nil { fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile) provisioner = "juju" } app.Provisioner, err = provision.Get(provisioner) if err != nil { fatal(err) } fmt.Printf("Using %q provisioner.\n\n", provisioner) qServer, err := config.GetString("queue-server") if err != nil { fatal(err) } fmt.Printf("Connected to queue server at %s.\n", qServer) go handleMessages() ticker := time.Tick(time.Minute) fmt.Println("tsuru collector agent started...") jujuCollect(ticker) } }
func assembleImageName(appName string) string { parts := make([]string, 0, 3) registry, _ := config.GetString("docker:registry") if registry != "" { parts = append(parts, registry) } repoNamespace, _ := config.GetString("docker:repository-namespace") parts = append(parts, repoNamespace, appName) return strings.Join(parts, "/") }
func (s *S) TestReadWriteURLUseUidFromConfigFile(c *gocheck.C) { uid, err := config.GetString("uid") c.Assert(err, gocheck.IsNil) host, err := config.GetString("host") c.Assert(err, gocheck.IsNil) config.Set("uid", "test") defer config.Set("uid", uid) remote := (&Repository{Name: "f#"}).ReadWriteURL() c.Assert(remote, gocheck.Equals, fmt.Sprintf("test@%s:f#.git", host)) }
// Conn reads the tsuru config and calls Open to get a database connection. // // Most tsuru packages should probably use this function. Open is intended for // use when supporting more than one database. func Conn() (*Storage, error) { url, _ := config.GetString("database:url") if url == "" { url = DefaultDatabaseURL } dbname, _ := config.GetString("database:name") if dbname == "" { dbname = DefaultDatabaseName } return Open(url, dbname) }
// Conn reads the tsuru config and calls Open to get a database connection. // // Most tsuru packages should probably use this function. Open is intended for // use when supporting more than one database. func Conn() (*Storage, error) { url, err := config.GetString("database:url") if err != nil { return nil, fmt.Errorf("configuration error: %s", err) } dbname, err := config.GetString("database:name") if err != nil { return nil, fmt.Errorf("configuration error: %s", err) } return Open(url, dbname) }
// SshURL formats the git ssh url and return it. If no remote is configured in // gandalf.conf, this method panics. func (r *Repository) SshURL() string { host, err := config.GetString("host") if err != nil { panic(err.Error()) } uid, err := config.GetString("uid") if err != nil { panic(err.Error()) } return fmt.Sprintf("%s@%s:%s.git", uid, host, r.Name) }
func (s *S) TestReadWriteURLWithSSH(c *gocheck.C) { config.Set("git:ssh:use", true) defer config.Unset("git:ssh:use") uid, err := config.GetString("uid") c.Assert(err, gocheck.IsNil) host, err := config.GetString("host") c.Assert(err, gocheck.IsNil) remote := (&Repository{Name: "lol"}).ReadWriteURL() expected := fmt.Sprintf("ssh://%s@%s/lol.git", uid, host) c.Assert(remote, gocheck.Equals, expected) }
func (bootstrapInstanceIDHealer) getS3Endpoint() *s3.S3 { access, err := config.GetString("aws:access-key-id") if err != nil { log.Fatal(err) } secret, err := config.GetString("aws:secret-access-key") if err != nil { log.Fatal(err) } auth := aws.Auth{AccessKey: access, SecretKey: secret} return s3.New(auth, aws.USEast) }
func (s *S) TestDeployCmds(c *gocheck.C) { app := testing.NewFakeApp("app-name", "python", 1) deployCmd, err := config.GetString("docker:deploy-cmd") c.Assert(err, gocheck.IsNil) version := "version" appRepo := repository.ReadOnlyURL(app.GetName()) user, err := config.GetString("docker:ssh:user") c.Assert(err, gocheck.IsNil) expected := []string{"sudo", "-u", user, deployCmd, appRepo} cmds, err := deployCmds(app, version) c.Assert(err, gocheck.IsNil) c.Assert(cmds, gocheck.DeepEquals, expected) }
// deployCmds returns the commands that is used when provisioner // deploy an unit. func deployCmds(app provision.App, version string) ([]string, error) { deployCmd, err := config.GetString("docker:deploy-cmd") if err != nil { return nil, err } appRepo := repository.ReadOnlyURL(app.GetName()) user, err := config.GetString("docker:ssh:user") if err != nil { return nil, err } cmds := []string{"sudo", "-u", user, deployCmd, appRepo, version} return cmds, nil }
func (s *S) TestRunContainerCmdReturnsCommandToRunContainer(c *gocheck.C) { app := testing.NewFakeApp("myapp", "python", 1) cmd, err := runContainerCmd(app) c.Assert(err, gocheck.IsNil) runBin, err := config.GetString("docker:run-cmd:bin") c.Assert(err, gocheck.IsNil) runArgs, err := config.GetString("docker:run-cmd:args") c.Assert(err, gocheck.IsNil) port, err := config.GetString("docker:run-cmd:port") c.Assert(err, gocheck.IsNil) runCmd := fmt.Sprintf("%s %s", runBin, runArgs) expected := []string{"docker", "run", "-d", "-p", port, fmt.Sprintf("%s/myapp", s.repoNamespace), runCmd} c.Assert(cmd, gocheck.DeepEquals, expected) }
func (c *container) ssh(stdout, stderr io.Writer, cmd string, args ...string) error { stderr = &filter{w: stderr, content: []byte("unable to resolve host")} user, err := config.GetString("docker:ssh:user") if err != nil { return err } sshArgs := []string{c.IP, "-l", user, "-o", "StrictHostKeyChecking no"} if keyFile, err := config.GetString("docker:ssh:private-key"); err == nil { sshArgs = append(sshArgs, "-i", keyFile) } sshArgs = append(sshArgs, "--", cmd) sshArgs = append(sshArgs, args...) return executor().Execute("ssh", sshArgs, nil, stdout, stderr) }
func getAWSAuth() aws.Auth { access, err := config.GetString("aws:access-key-id") if err != nil { panic("FATAL: aws:access-key-id must be defined in configuration file.") } secret, err := config.GetString("aws:secret-access-key") if err != nil { panic("FATAL: aws:secret-access-key must be defined in configuration file.") } return aws.Auth{ AccessKey: access, SecretKey: secret, } }
func loadConfig() { var err error if salt, err = config.GetString("auth:salt"); err != nil { salt = defaultSalt } if iface, err := config.Get("auth:token-expire-days"); err == nil { day := int64(iface.(int)) tokenExpire = time.Duration(day * 24 * int64(time.Hour)) } else { tokenExpire = defaultExpiration } if tokenKey, err = config.GetString("auth:token-key"); err != nil { tokenKey = defaultKey } }
// Connect uses database:url and database:name settings in config file and // connects to the database. If it cannot connect or these settings are not // defined, it will panic. func Connect() { url, err := config.GetString("database:url") if err != nil { panic(err) } name, err := config.GetString("database:name") if err != nil { panic(err) } s, err := mgo.Dial(url) if err != nil { panic(err) } Session.DB = s.DB(name) }
// Connect uses database:url and database:name settings in config file and // connects to the database. If it cannot connect or these settings are not // defined, it will panic. func Connect() { url, _ := config.GetString("database:url") if url == "" { url = "localhost:27017" } name, _ := config.GetString("database:name") if name == "" { name = "gandalf" } s, err := mgo.Dial(url) if err != nil { panic(err) } Session.DB = s.DB(name) }
func (s *S) TestNewBareShouldPassTemplateOptionWhenItExistsOnConfig(c *C) { bareTempl, err := config.GetString("git:bare:template") c.Assert(err, IsNil) bareLocation, err := config.GetString("git:bare:location") c.Assert(err, IsNil) barePath := path.Join(bareLocation, "foo.git") dir, err := commandmocker.Add("git", "$*") c.Assert(err, IsNil) defer commandmocker.Remove(dir) err = newBare("foo") c.Assert(err, IsNil) c.Assert(commandmocker.Ran(dir), Equals, true) expected := fmt.Sprintf("init %s --bare --template=%s", barePath, bareTempl) c.Assert(commandmocker.Output(dir), Equals, expected) }
func main() { dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)") configFile := flag.String("config", "/etc/gandalf.conf", "Gandalf configuration file") flag.Parse() err := config.ReadAndWatchConfigFile(*configFile) if err != nil { msg := `Could not find gandalf config file. Searched on %s. For an example conf check gandalf/etc/gandalf.conf file.\n %s` log.Panicf(msg, *configFile, err) } db.Connect() router := pat.New() router.Post("/user/:name/key", http.HandlerFunc(api.AddKey)) router.Del("/user/:name/key/:keyname", http.HandlerFunc(api.RemoveKey)) router.Get("/user/:name/keys", http.HandlerFunc(api.ListKeys)) router.Post("/user", http.HandlerFunc(api.NewUser)) router.Del("/user/:name", http.HandlerFunc(api.RemoveUser)) router.Post("/repository", http.HandlerFunc(api.NewRepository)) router.Post("/repository/grant", http.HandlerFunc(api.GrantAccess)) router.Del("/repository/revoke", http.HandlerFunc(api.RevokeAccess)) router.Del("/repository/:name", http.HandlerFunc(api.RemoveRepository)) router.Get("/repository/:name", http.HandlerFunc(api.GetRepository)) router.Put("/repository/:name", http.HandlerFunc(api.RenameRepository)) port, err := config.GetString("webserver:port") if err != nil { panic(err) } if !*dry { log.Fatal(http.ListenAndServe(port, router)) } }
func (p *JujuProvisioner) Provision(app provision.App) error { var buf bytes.Buffer charms, err := config.GetString("juju:charms-path") if err != nil { return errors.New(`Setting "juju:charms-path" is not defined.`) } args := []string{ "deploy", "--repository", charms, "local:" + app.GetPlatform(), app.GetName(), } err = runCmd(false, &buf, &buf, args...) out := buf.String() if err != nil { app.Log("Failed to create machine: "+out, "tsuru") return cmdError(out, err, args) } setOption := []string{ "set", app.GetName(), "app-repo=" + repository.ReadOnlyURL(app.GetName()), } runCmd(true, &buf, &buf, setOption...) if p.elbSupport() { router, err := Router() if err != nil { return err } if err = router.AddBackend(app.GetName()); err != nil { return err } p.enqueueUnits(app.GetName()) } return nil }
// GitURL formats the git url and return it. If no host is configured in // gandalf.conf, this method panics. func (r *Repository) GitURL() string { host, err := config.GetString("host") if err != nil { panic(err.Error()) } return fmt.Sprintf("git://%s/%s.git", host, r.Name) }