Example #1
0
func main() {
	for Args = os.Args[1:]; Args != nil && len(Args) > 0 && Args[0][0] == '-'; Args = Args[1:] {
		switch Args[0] {
		case "--no-color":
			color = false
			slog.DisableColor()
		case "--log":
			tracefile, err := os.OpenFile(Args[1], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
			if err == nil {
				slog.TraceLogger = slog.NewTraceLogger(tracefile)
				Args = Args[1:]
			} else {
				fmt.Printf("Could not open trace file %s", Args[1])
				return
			}
		case "--file-change-delay":
			if len(Args) > 1 {
				delay, err := time.ParseDuration(Args[1])
				if err != nil {
					execManPage("zeus")
				}
				Args = Args[1:]
				restarter.FileChangeWindow = delay
			} else {
				execManPage("zeus")
			}
		case "--version":
			printVersion()
			return
		}
	}
	if len(Args) == 0 {
		execManPage("zeus")
	}

	if generalHelpRequested(Args) {
		execManPage("zeus")
	} else if Args[0] == "help" {
		commandSpecificHelp(Args)
	} else if Args[0] == "version" {
		printVersion()
	} else if Args[0] == "start" {
		zeusmaster.Run()
	} else if Args[0] == "init" {
		zeusInit()
	} else if Args[0] == "commands" {
		zeusCommands()
	} else {
		tree := config.BuildProcessTree()
		for _, name := range tree.AllCommandsAndAliases() {
			if Args[0] == name {
				zeusclient.Run()
				return
			}
		}

		commandNotFound(Args[0])
	}
}
Example #2
0
func Run(color bool) {
	if !color {
		slog.DisableColor()
		DisableErrorColor()
	}
	slog.StartingZeus()

	var tree *ProcessTree = BuildProcessTree()

	exitNow = make(chan int)

	localMasterFile, remoteMasterFile, err := unixsocket.Socketpair(syscall.SOCK_DGRAM)
	if err != nil {
		panic(err)
	}

	localMasterSocket, err := unixsocket.NewUsockFromFile(localMasterFile)
	if err != nil {
		panic(err)
	}

	quit1 := make(chan bool)
	quit2 := make(chan bool)
	quit3 := make(chan bool)

	go StartSlaveMonitor(tree, localMasterSocket, remoteMasterFile, quit1)
	go StartClientHandler(tree, quit2)
	go StartFileMonitor(tree, quit3)

	quit := make(chan bool, 1)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		// FIXME: Unprecedented levels of jank, right here.
		terminateComponents(quit1, quit2, quit3, quit)
	}()

	go func() {
		exitStatus = <-exitNow
		terminateComponents(quit1, quit2, quit3, quit)
	}()

	<-quit
	<-quit
	<-quit

	os.Exit(exitStatus)
}
Example #3
0
func Run(color bool) {
	exitNow = make(chan int)

	if !color {
		slog.DisableColor()
	}
	startingZeus()

	var tree *ProcessTree = BuildProcessTree()

	quit1 := make(chan bool)
	quit2 := make(chan bool)
	quit3 := make(chan bool)
	quit4 := make(chan bool)

	go StartSlaveMonitor(tree, quit1)
	go StartClientHandler(tree, quit2)
	go StartFileMonitor(tree, quit3)
	go StartStatusChart(tree, quit4)

	quit := make(chan bool)

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		<-c
		terminateComponents(quit1, quit2, quit3, quit4, quit)
	}()

	go func() {
		exitStatus = <-exitNow
		terminateComponents(quit1, quit2, quit3, quit4, quit)
	}()

	<-quit
	<-quit
	<-quit
	<-quit

	os.Exit(exitStatus)
}
Example #4
0
func main() {
	if len(os.Args) == 1 {
		execManPage("zeus")
	}

	var args []string
	if os.Args[1] == "--no-color" {
		color = false
		slog.DisableColor()
		args = os.Args[2:]
	} else {
		args = os.Args[1:]
	}

	if generalHelpRequested(args) {
		execManPage("zeus")
	} else if args[0] == "help" {
		commandSpecificHelp(args)
	} else if args[0] == "version" || args[0] == "--version" {
		println("Zeus version " + zeusversion.VERSION)
	} else if args[0] == "start" {
		zeusmaster.Run()
	} else if args[0] == "init" {
		zeusInit()
	} else if args[0] == "commands" {
		zeusCommands()
	} else {
		tree := zeusmaster.BuildProcessTree()
		for _, name := range tree.AllCommandsAndAliases() {
			if args[0] == name {
				zeusclient.Run()
				return
			}
		}

		commandNotFound(args[0])
	}
}
Example #5
0
File: zeus.go Project: burke/zeus
func main() {
	args := os.Args[1:]
	configFile := "zeus.json"
	fileChangeDelay := filemonitor.DefaultFileChangeDelay

	for ; args != nil && len(args) > 0 && args[0][0] == '-'; args = args[1:] {
		switch args[0] {
		case "--no-color":
			color = false
			slog.DisableColor()
		case "--log":
			tracefile, err := os.OpenFile(args[1], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
			if err == nil {
				slog.SetTraceLogger(slog.NewTraceLogger(tracefile))
				args = args[1:]
			} else {
				fmt.Printf("Could not open trace file %s\n", args[1])
				return
			}
		case "--file-change-delay":
			if len(args) > 1 {
				delay, err := time.ParseDuration(args[1])
				if err != nil {
					execManPage("zeus")
				}
				args = args[1:]
				fileChangeDelay = delay
			} else {
				execManPage("zeus")
			}
		case "--config":
			_, err := os.Stat(args[1])
			if err != nil {
				fmt.Printf("Config file doesn't exist: %s (%e)\n", args[1], err)
				return
			}
			configFile = args[1]
			args = args[1:]
		case "--version":
			printVersion()
			return
		}
	}
	if len(args) == 0 {
		execManPage("zeus")
		return
	}

	if generalHelpRequested(args) {
		execManPage("zeus")
	} else if args[0] == "help" {
		commandSpecificHelp(args)
	} else if args[0] == "version" {
		printVersion()
	} else if args[0] == "start" {
		os.Exit(zeusmaster.Run(configFile, fileChangeDelay))
	} else if args[0] == "init" {
		zeusInit()
	} else if args[0] == "commands" {
		zeusCommands(configFile)
	} else {
		tree := config.BuildProcessTree(configFile, nil)
		for _, name := range tree.AllCommandsAndAliases() {
			if args[0] == name {
				// Don't confuse the master by sending *full* args to
				// it; just those that are not zeus-specific.
				os.Exit(zeusclient.Run(args, os.Stdin, os.Stdout))
			}
		}

		commandNotFound(args[0])
	}
}
Example #6
0
func doRun(color bool) int {
	if !color {
		slog.DisableColor()
		DisableErrorColor()
	}

	if os.Getenv("RAILS_ENV") != "" {
		println("Warning: Specifying a Rails environment via RAILS_ENV has no effect for commands run with zeus.")
	}

	master, slave, err := pty.Open()
	if err != nil {
		panic(err)
	}
	defer master.Close()
	if ttyutils.IsTerminal(os.Stdout.Fd()) {
		oldState, err := ttyutils.MakeTerminalRaw(os.Stdout.Fd())
		if err != nil {
			panic(err)
		}
		defer ttyutils.RestoreTerminalState(os.Stdout.Fd(), oldState)
	}

	ttyutils.MirrorWinsize(os.Stdout, master)

	addr, err := net.ResolveUnixAddr("unixgram", zeusSockName)
	if err != nil {
		panic("Can't resolve server address")
	}

	conn, err := net.DialUnix("unix", nil, addr)
	if err != nil {
		ErrorCantConnectToMaster()
	}
	usock := unixsocket.NewUsock(conn)

	msg := CreateCommandAndArgumentsMessage(os.Args[1], os.Args[2:])
	usock.WriteMessage(msg)
	usock.WriteFD(int(slave.Fd()))
	slave.Close()

	msg, err = usock.ReadMessage()
	if err != nil {
		panic(err)
	}

	parts := strings.Split(msg, "\000")
	commandPid, err := strconv.Atoi(parts[0])
	defer func() {
		if commandPid > 0 {
			// Just in case.
			syscall.Kill(commandPid, 9)
		}
	}()

	if err != nil {
		panic(err)
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGWINCH, syscall.SIGCONT)
	go func() {
		for sig := range c {
			if sig == syscall.SIGCONT {
				syscall.Kill(commandPid, syscall.SIGCONT)
			} else if sig == syscall.SIGWINCH {
				ttyutils.MirrorWinsize(os.Stdout, master)
				syscall.Kill(commandPid, syscall.SIGWINCH)
			}
		}
	}()

	var exitStatus int = -1
	if len(parts) > 2 {
		exitStatus, err = strconv.Atoi(parts[0])
		if err != nil {
			panic(err)
		}
	}

	eof := make(chan bool)
	go func() {
		for {
			buf := make([]byte, 1024)
			n, err := master.Read(buf)
			if err != nil {
				eof <- true
				break
			}
			os.Stdout.Write(buf[:n])
		}
	}()

	go func() {
		buf := make([]byte, 8192)
		for {
			n, err := os.Stdin.Read(buf)
			if err != nil {
				eof <- true
				break
			}
			for i := 0; i < n; i++ {
				switch buf[i] {
				case sigInt:
					syscall.Kill(commandPid, syscall.SIGINT)
				case sigQuit:
					syscall.Kill(commandPid, syscall.SIGQUIT)
				case sigTstp:
					syscall.Kill(commandPid, syscall.SIGTSTP)
					syscall.Kill(os.Getpid(), syscall.SIGTSTP)
				}
			}
			master.Write(buf[:n])
		}
	}()

	<-eof

	if exitStatus == -1 {
		msg, err = usock.ReadMessage()
		if err != nil {
			panic(err)
		}
		parts := strings.Split(msg, "\000")
		exitStatus, err = strconv.Atoi(parts[0])
		if err != nil {
			panic(err)
		}
	}

	return exitStatus
}
Example #7
0
func main() {
	for Args = os.Args[1:]; Args != nil && len(Args) > 0 && Args[0][0] == '-'; Args = Args[1:] {
		switch Args[0] {
		case "--no-color":
			color = false
			slog.DisableColor()
		case "--log":
			tracefile, err := os.OpenFile(Args[1], os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
			if err == nil {
				slog.SetTraceLogger(slog.NewTraceLogger(tracefile))
				Args = Args[1:]
			} else {
				fmt.Printf("Could not open trace file %s\n", Args[1])
				return
			}
		case "--file-change-delay":
			if len(Args) > 1 {
				delay, err := time.ParseDuration(Args[1])
				if err != nil {
					execManPage("zeus")
				}
				Args = Args[1:]
				restarter.FileChangeWindow = delay
			} else {
				execManPage("zeus")
			}
		case "--config":
			_, err := os.Stat(Args[1])
			if err != nil {
				fmt.Printf("Config file doesn't exist: %s (%e)\n", Args[1], err)
				return
			}
			config.ConfigFile = Args[1]
			Args = Args[1:]
		case "--version":
			printVersion()
			return
		}
	}
	if len(Args) == 0 {
		execManPage("zeus")
	}

	// Don't confuse the master by sending *full* args to it; just those that are
	// not zeus-specific.
	config.Args = Args

	if generalHelpRequested(Args) {
		execManPage("zeus")
	} else if Args[0] == "help" {
		commandSpecificHelp(Args)
	} else if Args[0] == "version" {
		printVersion()
	} else if Args[0] == "start" {
		zeusmaster.Run()
	} else if Args[0] == "init" {
		zeusInit()
	} else if Args[0] == "commands" {
		zeusCommands()
	} else {
		tree := config.BuildProcessTree()
		for _, name := range tree.AllCommandsAndAliases() {
			if Args[0] == name {
				zeusclient.Run()
				return
			}
		}

		commandNotFound(Args[0])
	}
}