Example #1
0
func (this *ZkInstall) Run(args []string) (exitCode int) {
	cmdFlags := flag.NewFlagSet("zkinstall", flag.ContinueOnError)
	cmdFlags.Usage = func() { this.Ui.Output(this.Help()) }
	cmdFlags.StringVar(&this.rootPath, "root", "/var/wd/zookeeper", "")
	cmdFlags.StringVar(&this.myId, "id", "", "")
	cmdFlags.StringVar(&this.servers, "servers", "", "")
	cmdFlags.BoolVar(&this.singleMode, "single", false, "")
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	if !ctx.CurrentUserIsRoot() {
		this.Ui.Error("requires root priviledges!")
		return 1
	}

	if !this.singleMode {
		if validateArgs(this, this.Ui).
			require("-id", "-servers").
			invalid(args) {
			return 2
		}
	}

	// create dirs
	this.rootPath = strings.TrimSuffix(this.rootPath, "/")
	for _, d := range []string{"bin", "conf", "data", "lib", "log"} {
		swallow(os.MkdirAll(fmt.Sprintf("%s/%s", this.rootPath, d), 0755))
	}

	type templateVar struct {
		MyId     string
		RootPath string
		Servers  string
	}
	data := templateVar{
		MyId:     this.myId,
		RootPath: this.rootPath,
	}
	if !this.singleMode {
		servers := make([]string, 0)
		for _, s := range strings.Split(this.servers, ",") {
			parts := strings.SplitN(s, ":", 2)
			servers = append(servers, fmt.Sprintf("server.%s=%s:2888:3888",
				parts[0], parts[1]))
		}
		data.Servers = strings.Join(servers, "\n")
	}

	// copy all files in bin and lib
	for srcDir, dstDir := range map[string]string{
		"template/zk/bin": fmt.Sprintf("%s/bin", this.rootPath),
		"template/zk/lib": fmt.Sprintf("%s/lib", this.rootPath)} {
		files, err := AssetDir(srcDir)
		swallow(err)
		for _, srcFile := range files {
			_, dstFile := path.Split(srcFile)
			from := fmt.Sprintf("%s/%s", srcDir, srcFile)
			to := fmt.Sprintf("%s/%s", dstDir, dstFile)
			var perm os.FileMode = 0644
			if strings.HasSuffix(srcDir, "/bin") {
				perm = 0755
			}
			writeFileFromTemplate(from, to, perm, nil, nil)
		}
	}

	// zk jar
	writeFileFromTemplate("template/zk/zookeeper-3.4.6.jar",
		fmt.Sprintf("%s/zookeeper-3.4.6.jar", this.rootPath), 0644, nil, nil)

	// tempated conf
	writeFileFromTemplate("template/zk/conf/zoo.cfg",
		fmt.Sprintf("%s/conf/zoo.cfg", this.rootPath), 0644, data, nil)
	writeFileFromTemplate("template/zk/conf/log4j.properties",
		fmt.Sprintf("%s/conf/log4j.properties", this.rootPath), 0644, nil, nil)

	// templated data/myid
	if !this.singleMode {
		writeFileFromTemplate("template/zk/data/myid",
			fmt.Sprintf("%s/data/myid", this.rootPath), 0644, data, nil)
	}

	// templated init.d/
	writeFileFromTemplate("template/init.d/zookeeper",
		"/etc/init.d/zookeeper", 0755, data, nil)

	this.Ui.Info("zookeeper installed on localhost")
	this.Ui.Warn(fmt.Sprintf("NOW, please run the following command:"))
	this.Ui.Warn("yum install -y jdk-1.7.0_65-fcs.x86_64")
	this.Ui.Output(color.Red("chkconfig --add zookeeper"))
	this.Ui.Output(color.Red("/etc/init.d/zookeeper start"))

	return
}
Example #2
0
// TODO
// 1. broker id assignment
// 2. port assignment
func (this *Deploy) Run(args []string) (exitCode int) {
	cmdFlags := flag.NewFlagSet("deploy", flag.ContinueOnError)
	cmdFlags.Usage = func() { this.Ui.Output(this.Help()) }
	cmdFlags.StringVar(&this.zone, "z", "", "")
	cmdFlags.StringVar(&this.cluster, "c", "", "")
	cmdFlags.StringVar(&this.kafkaBaseDir, "kafka.base", ctx.KafkaHome(), "")
	cmdFlags.StringVar(&this.brokerId, "broker.id", "", "")
	cmdFlags.StringVar(&this.tcpPort, "port", "", "")
	cmdFlags.StringVar(&this.rootPah, "root", "/var/wd", "")
	cmdFlags.StringVar(&this.ip, "ip", "", "")
	cmdFlags.StringVar(&this.logDirs, "log.dirs", "", "")
	cmdFlags.StringVar(&this.runAs, "user", "sre", "")
	cmdFlags.StringVar(&this.uninstall, "uninstall", "", "")
	cmdFlags.BoolVar(&this.demoMode, "demo", false, "")
	cmdFlags.BoolVar(&this.installKafkaOnly, "kfkonly", false, "")
	cmdFlags.BoolVar(&this.dryRun, "dryrun", true, "")
	cmdFlags.StringVar(&this.influxDbAddr, "influx", "", "")
	cmdFlags.StringVar(&this.kafkaVer, "ver", "2.10-0.8.2.2", "")
	if err := cmdFlags.Parse(args); err != nil {
		return 1
	}

	if this.uninstall != "" {
		serverProperties := fmt.Sprintf("%s/config/server.properties", this.uninstall)
		lines, err := gio.ReadLines(serverProperties)
		if err != nil {
			this.Ui.Error(err.Error())
			return 2
		}
		var logDirs []string
		for _, line := range lines {
			if strings.HasPrefix(line, "log.dirs") {
				parts := strings.SplitN(line, "=", 2)
				logDirs = strings.Split(parts[1], ",")
				break
			}
		}
		if len(logDirs) == 0 {
			this.Ui.Error("empty log.dirs")
			return 2
		}

		for _, logDir := range logDirs {
			this.Ui.Output(fmt.Sprintf("rm -rf %s", logDir))
		}
		name := filepath.Base(this.uninstall)
		this.Ui.Output(fmt.Sprintf("chkconfig --del %s", name))
		this.Ui.Output(fmt.Sprintf("rm -f /etc/init.d/%s", name))
		this.Ui.Output(fmt.Sprintf("rm -rf %s", this.uninstall))
		return 0
	}

	if !ctx.CurrentUserIsRoot() {
		this.Ui.Error("requires root priviledges!")
		return 1
	}

	if !strings.HasSuffix(this.kafkaBaseDir, this.kafkaVer) {
		this.Ui.Error(fmt.Sprintf("kafka.base[%s] does not match ver[%s]",
			this.kafkaBaseDir, this.kafkaVer))
		return 1
	}

	if this.installKafkaOnly {
		this.installKafka()
		return
	}

	if validateArgs(this, this.Ui).
		require("-z", "-c").
		invalid(args) {
		return 2
	}

	this.zkzone = zk.NewZkZone(zk.DefaultConfig(this.zone, ctx.ZoneZkAddrs(this.zone)))
	clusers := this.zkzone.Clusters()
	zkchroot, present := clusers[this.cluster]
	if !present {
		this.Ui.Error(fmt.Sprintf("run 'gk clusters -z %s -add %s -p $zkchroot' first!",
			this.zone, this.cluster))
		return 1
	}

	var err error
	this.userInfo, err = user.Lookup(this.runAs)
	swallow(err)

	if this.demoMode {
		this.demo()
		return
	}

	if validateArgs(this, this.Ui).
		require("-broker.id", "-port", "-ip", "-log.dirs").
		invalid(args) {
		return 2
	}

	if this.dryRun {
		this.Ui.Output(fmt.Sprintf("mkdir %s/logs and chown to %s",
			this.instanceDir(), this.runAs))
	}
	err = os.MkdirAll(fmt.Sprintf("%s/logs", this.instanceDir()), 0755)
	swallow(err)
	chown(fmt.Sprintf("%s/logs", this.instanceDir()), this.userInfo)

	invalidDir := this.validateLogDirs(this.logDirs)
	if invalidDir != "" {
		this.Ui.Error(fmt.Sprintf("%s in log.dirs not exists!", invalidDir))
		return 2
	}

	// prepare the root directory
	this.rootPah = strings.TrimSuffix(this.rootPah, "/")
	if this.dryRun {
		this.Ui.Output(fmt.Sprintf("mkdir %s/bin and chown to %s",
			this.instanceDir(), this.runAs))
	}
	err = os.MkdirAll(fmt.Sprintf("%s/bin", this.instanceDir()), 0755)
	swallow(err)
	chown(fmt.Sprintf("%s/bin", this.instanceDir()), this.userInfo)

	if this.dryRun {
		this.Ui.Output(fmt.Sprintf("mkdir %s/config and chown to %s",
			this.instanceDir(), this.runAs))
	}
	err = os.MkdirAll(fmt.Sprintf("%s/config", this.instanceDir()), 0755)
	swallow(err)
	chown(fmt.Sprintf("%s/config", this.instanceDir()), this.userInfo)

	type templateVar struct {
		KafkaBase             string
		BrokerId              string
		TcpPort               string
		Ip                    string
		User                  string
		ZkChroot              string
		ZkAddrs               string
		InstanceDir           string
		LogDirs               string
		IoThreads             string
		NetworkThreads        string
		InfluxReporterEnabled string
		InfluxDbHost          string
		InfluxDbPort          string
	}
	if this.influxDbAddr != "" {
		this.influxDbHost, this.influxdbPort, err = net.SplitHostPort(this.influxDbAddr)
		if err != nil {
			this.Ui.Error(err.Error())
			return 2
		}
		if this.influxDbHost == "" || this.influxdbPort == "" {
			this.Ui.Error("empty influxdb host or port")
			return 2
		}
	}

	influxReporterEnabled := "false"
	if this.influxDbHost != "" {
		influxReporterEnabled = "true"
	}
	data := templateVar{
		ZkAddrs:               this.zkzone.ZkAddrs(),
		ZkChroot:              zkchroot,
		KafkaBase:             this.kafkaBaseDir,
		BrokerId:              this.brokerId,
		Ip:                    this.ip,
		InstanceDir:           this.instanceDir(),
		User:                  this.runAs,
		TcpPort:               this.tcpPort,
		LogDirs:               this.logDirs,
		InfluxReporterEnabled: influxReporterEnabled,
		InfluxDbHost:          this.influxDbHost,
		InfluxDbPort:          this.influxdbPort,
	}
	data.IoThreads = strconv.Itoa(3 * len(strings.Split(data.LogDirs, ",")))
	networkThreads := ctx.NumCPU() / 2
	if networkThreads < 2 {
		networkThreads = 2
	}
	data.NetworkThreads = strconv.Itoa(networkThreads) // TODO not used yet

	// create the log.dirs directory and chown to sre
	logDirs := strings.Split(this.logDirs, ",")
	for _, logDir := range logDirs {
		if this.dryRun {
			this.Ui.Output(fmt.Sprintf("mkdir %s and chown to %s",
				logDir, this.runAs))
		}

		swallow(os.MkdirAll(logDir, 0755))
		chown(logDir, this.userInfo)
	}

	// package the kafka runtime together
	if !gio.DirExists(this.kafkaLibDir()) {
		this.installKafka()
	}

	// bin
	writeFileFromTemplate("template/bin/kafka-topics.sh",
		fmt.Sprintf("%s/bin/kafka-topics.sh", this.instanceDir()), 0755, nil, this.userInfo)
	writeFileFromTemplate("template/bin/kafka-reassign-partitions.sh",
		fmt.Sprintf("%s/bin/kafka-reassign-partitions.sh", this.instanceDir()), 0755, nil, this.userInfo)
	writeFileFromTemplate("template/bin/kafka-preferred-replica-election.sh",
		fmt.Sprintf("%s/bin/kafka-preferred-replica-election.sh", this.instanceDir()), 0755, nil, this.userInfo)

	writeFileFromTemplate("template/bin/kafka-run-class.sh",
		fmt.Sprintf("%s/bin/kafka-run-class.sh", this.instanceDir()), 0755, data, this.userInfo)
	writeFileFromTemplate("template/bin/kafka-server-start.sh",
		fmt.Sprintf("%s/bin/kafka-server-start.sh", this.instanceDir()), 0755, data, this.userInfo)
	writeFileFromTemplate("template/bin/setenv.sh",
		fmt.Sprintf("%s/bin/setenv.sh", this.instanceDir()), 0755, data, this.userInfo)

	// /etc/init.d/
	writeFileFromTemplate("template/init.d/kafka",
		fmt.Sprintf("/etc/init.d/%s", this.clusterName()), 0755, data, nil)

	// config
	writeFileFromTemplate("template/config/server.properties",
		fmt.Sprintf("%s/config/server.properties", this.instanceDir()), 0644, data, this.userInfo)
	writeFileFromTemplate("template/config/log4j.properties",
		fmt.Sprintf("%s/config/log4j.properties", this.instanceDir()), 0644, data, this.userInfo)

	this.Ui.Warn(fmt.Sprintf("NOW, please run the following command:"))
	this.Ui.Output(color.Red("confirm log.retention.hours"))
	this.Ui.Output(color.Red("chkconfig --add %s", this.clusterName()))
	this.Ui.Output(color.Red("/etc/init.d/%s start", this.clusterName()))

	return
}