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 }
// 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 }