Beispiel #1
0
// 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)
	}
}
Beispiel #2
0
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)
	}
}
Beispiel #3
0
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()
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
// 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))
	}
}
Beispiel #9
0
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))
}
Beispiel #10
0
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))
}
Beispiel #11
0
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)
	}
}
Beispiel #12
0
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))
}
Beispiel #14
0
// 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)
}
Beispiel #15
0
// 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)
}
Beispiel #16
0
// 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)
}
Beispiel #18
0
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)
}
Beispiel #19
0
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)
}
Beispiel #20
0
// 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
}
Beispiel #21
0
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)
}
Beispiel #22
0
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)
}
Beispiel #23
0
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,
	}
}
Beispiel #24
0
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
	}
}
Beispiel #25
0
// 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)
}
Beispiel #27
0
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)
}
Beispiel #28
0
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))
	}
}
Beispiel #29
0
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
}
Beispiel #30
0
// 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)
}