예제 #1
0
func cmdInfo(c *cli.Context) error {
	conf, err := config.Open(c.GlobalString("config"))
	if err != nil {
		Logger.Fatalf("Cannot load configuration: %v", err)
		return nil
	}

	fmt.Printf("Debug mode (client): %v\n", os.Getenv("ASSH_DEBUG") == "1")
	cliPath, _ := osext.Executable()
	fmt.Printf("CLI Path: %s\n", cliPath)
	fmt.Printf("Go version: %s\n", runtime.Version())
	fmt.Printf("OS/Arch: %s/%s\n", runtime.GOOS, runtime.GOARCH)
	fmt.Println("")
	fmt.Printf("RC files:\n")
	homeDir := utils.GetHomeDir()
	for _, filename := range conf.IncludedFiles() {
		relativeFilename := strings.Replace(filename, homeDir, "~", -1)
		fmt.Printf("- %s\n", relativeFilename)
	}
	fmt.Println("")
	fmt.Println("Statistics:")
	fmt.Printf("- %d hosts\n", len(conf.Hosts))
	fmt.Printf("- %d templates\n", len(conf.Templates))
	fmt.Printf("- %d included files\n", len(conf.IncludedFiles()))
	// FIXME: print info about connections/running processes
	// FIXME: print info about current config file version

	return nil
}
예제 #2
0
파일: util.go 프로젝트: emccode/dvdcli
func GetThisPathParts() (dirPath, fileName, absPath string) {
	exeFile, err := osext.Executable()
	if err != nil {
		panic(err)
	}
	return GetPathParts(exeFile)
}
예제 #3
0
func monitor(c *WrapConfig) (int, error) {

	// If we're the child process, absorb panics.
	if Wrapped(c) {
		panicCh := make(chan string)

		go trackPanic(os.Stdin, os.Stderr, c.DetectDuration, panicCh)

		// Wait on the panic data
		panicTxt := <-panicCh
		if panicTxt != "" {
			if !c.HidePanic {
				os.Stderr.Write([]byte(panicTxt))
			}

			c.Handler(panicTxt)
		}

		os.Exit(0)
	}

	exePath, err := osext.Executable()
	if err != nil {
		return -1, err
	}
	cmd := exec.Command(exePath, os.Args[1:]...)

	read, write, err := os.Pipe()
	if err != nil {
		return -1, err
	}

	cmd.Stdin = read
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Env = append(os.Environ(), c.CookieKey+"="+c.CookieValue)

	if err != nil {
		return -1, err
	}
	err = cmd.Start()
	if err != nil {
		return -1, err
	}

	err = syscall.Dup2(int(write.Fd()), int(os.Stderr.Fd()))
	if err != nil {
		return -1, err
	}

	return -1, nil
}
예제 #4
0
func TestPanicHandler(t *testing.T) {
	startTestServer()

	exePath, err := osext.Executable()
	if err != nil {
		t.Fatal(err)
	}

	// Use the same trick as panicwrap() to re-run ourselves.
	// In the init() block below, we will then panic.
	cmd := exec.Command(exePath, os.Args[1:]...)
	cmd.Env = append(os.Environ(), "BUGSNAG_API_KEY="+testAPIKey, "BUGSNAG_ENDPOINT="+testEndpoint, "please_panic=please_panic")

	if err = cmd.Start(); err != nil {
		t.Fatal(err)
	}

	if err = cmd.Wait(); err.Error() != "exit status 2" {
		t.Fatal(err)
	}

	json, err := simplejson.NewJson(<-postedJSON)
	if err != nil {
		t.Fatal(err)
	}

	event := json.Get("events").GetIndex(0)

	if event.Get("severity").MustString() != "error" {
		t.Errorf("severity should be error")
	}
	exception := event.Get("exceptions").GetIndex(0)

	if exception.Get("message").MustString() != "ruh roh" {
		t.Errorf("caught wrong panic")
	}

	if exception.Get("errorClass").MustString() != "panic" {
		t.Errorf("caught wrong panic")
	}

	frame := exception.Get("stacktrace").GetIndex(1)

	// Yeah, we just caught a panic from the init() function below and sent it to the server running above (mindblown)
	if frame.Get("inProject").MustBool() != true ||
		frame.Get("file").MustString() != "panicwrap_test.go" ||
		frame.Get("lineNumber").MustInt() == 0 {
		t.Errorf("stack trace seemed wrong: %v", frame)
	}
}
예제 #5
0
파일: updater.go 프로젝트: catalyzeio/cli
func (u *Updater) update() error {
	path, err := osext.Executable()
	if err != nil {
		return err
	}
	old, err := os.Open(path)
	if err != nil {
		return err
	}
	defer old.Close()

	err = u.FetchInfo()
	if err != nil {
		return err
	}
	if u.Info.Version <= u.CurrentVersion {
		return nil
	}

	bin, err := u.fetchAndVerifyFullBin()
	if err != nil {
		if err == ErrHashMismatch {
			logrus.Warnln("update: hash mismatch from full binary")
		} else {
			logrus.Warnln("update: error fetching full binary,", err)
		}
		logrus.Warnln("update: please update your CLI manually by downloading the latest version for your OS here https://github.com/catalyzeio/cli/releases")
		return err
	}

	// close the old binary before installing because on windows
	// it can't be renamed if a handle to the file is still open
	old.Close()

	err, errRecover := up.FromStream(bytes.NewBuffer(bin))
	if errRecover != nil {
		return fmt.Errorf("update and recovery errors: %q %q", err, errRecover)
	}
	if err != nil {
		return err
	}
	logrus.Println("update: your CLI has been successfully updated!")
	return nil
}
예제 #6
0
func verifyExeDirWriteable() error {
	exe, err := osext.Executable()
	if err != nil {
		return exeGenericError()
	}
	exeDir := filepath.Dir(exe)
	f, err := os.Open(exeDir)
	if err != nil {
		return exeGenericError()
	}
	info, err := f.Stat()
	if err != nil {
		return exeGenericError()
	}
	usr, err := user.Current()
	if err != nil {
		return exeGenericError()
	}
	ownerID := strconv.FormatUint(uint64(info.Sys().(*syscall.Stat_t).Uid), 10)
	groupID := strconv.FormatUint(uint64(info.Sys().(*syscall.Stat_t).Gid), 10)
	// permissions are the 9 least significant bits
	mode := uint32(info.Mode()) & uint32((1<<9)-1)
	// Ex: 7   7   7
	//    111 111 111
	//         ^   ^
	groupWriteAble := uint32(1 << 4)
	globalWriteAble := uint32(1 << 1)
	// if user doesn't own the directory, and the directory isn't globally writeable,
	// and it is false that the directory is group writeable and the user is part of
	// the group, then we can't update.
	if ownerID != usr.Uid &&
		(mode&globalWriteAble) != globalWriteAble &&
		!((mode&groupWriteAble) == groupWriteAble && groupID == usr.Gid) {
		return fmt.Errorf("Your CLI cannot update, because your user cannot directly write to the directory it is in, \"%s\". Run the update command as the owner of the directory, or do the update manually.", exeDir)
	}
	return nil
}
예제 #7
0
// runnerConfiguration creates a runnerConfiguration resolving all the
// configurations from command line and provided configuration files.
func (c *ConfigurationManager) runnerConfiguration(loadDockerVersion versionutil.Version) (runnerConfiguration, error) {
	// TODO: eliminate suites and just use arguments
	var conf string
	// Get first flag
	if flag.NArg() == 0 {
		cwd, err := os.Getwd()
		if err != nil {
			return runnerConfiguration{}, err
		}
		conf = filepath.Join(cwd, "golem.conf")
		logrus.Debugf("No configuration given, trying current directory %s", conf)
	} else {
		absPath, err := filepath.Abs(flag.Arg(0))
		if err != nil {
			return runnerConfiguration{}, err
		}

		info, err := os.Stat(absPath)
		if err != nil {
			return runnerConfiguration{}, err
		}
		if info.IsDir() {
			absPath = filepath.Join(absPath, "golem.conf")
			if _, err := os.Stat(absPath); err != nil {
				return runnerConfiguration{}, err

			}
		}
		conf = absPath

	}

	suites, err := parseSuites(flag.Args())
	if err != nil {
		return runnerConfiguration{}, err
	}

	// TODO: Support non-linux by downloading and replacing executable path
	executablePath, err := osext.Executable()
	if err != nil {
		return runnerConfiguration{}, fmt.Errorf("error getting path to executable: %s", err)
	}

	runnerConfig := runnerConfiguration{
		ExecutableName: "golem_runner",
		ExecutablePath: executablePath,
	}

	for _, suite := range suites {
		resolver := newMultiResolver(c.flagResolver, suite, globalDefault)

		registrySuite := SuiteConfiguration{
			Name:           resolver.Name(),
			Path:           resolver.Path(),
			DockerInDocker: resolver.Dind(),
		}

		baseConf := BaseImageConfiguration{
			Base:              resolver.BaseImage(),
			ExtraImages:       resolver.Images(),
			DockerLoadVersion: loadDockerVersion,
			DockerVersion:     versionutil.Version(c.dockerVersion),
		}

		instances := resolver.Instances()

		for idx, instance := range instances {
			name := registrySuite.Name
			if len(instances) > 1 {
				name = fmt.Sprintf("%s-%d", name, idx+1)
			}
			imageConf := baseConf
			imageConf.CustomImages = instance.CustomImages

			conf := InstanceConfiguration{
				Name:             name,
				BaseImage:        imageConf,
				RunConfiguration: instance.RunConfiguration,
			}
			registrySuite.Instances = append(registrySuite.Instances, conf)
		}

		runnerConfig.Suites = append(runnerConfig.Suites, registrySuite)
	}

	return runnerConfig, nil
}
예제 #8
0
func wrap(c *WrapConfig) (int, error) {

	// If we're already wrapped, exit out.
	if Wrapped(c) {
		return -1, nil
	}

	// Get the path to our current executable
	exePath, err := osext.Executable()
	if err != nil {
		return -1, err
	}

	// Pipe the stderr so we can read all the data as we look for panics
	stderr_r, stderr_w := io.Pipe()

	// doneCh is closed when we're done, signaling any other goroutines
	// to end immediately.
	doneCh := make(chan struct{})

	// panicCh is the channel on which the panic text will actually be
	// sent.
	panicCh := make(chan string)

	// On close, make sure to finish off the copying of data to stderr
	defer func() {
		defer close(doneCh)
		stderr_w.Close()
		<-panicCh
	}()

	// Start the goroutine that will watch stderr for any panics
	go trackPanic(stderr_r, c.Writer, c.DetectDuration, panicCh)

	// Create the writer for stdout that we're going to use
	var stdout_w io.Writer = os.Stdout
	if c.Stdout != nil {
		stdout_w = c.Stdout
	}

	// Build a subcommand to re-execute ourselves. We make sure to
	// set the environmental variable to include our cookie. We also
	// set stdin/stdout to match the config. Finally, we pipe stderr
	// through ourselves in order to watch for panics.
	cmd := exec.Command(exePath, os.Args[1:]...)
	cmd.Env = append(os.Environ(), c.CookieKey+"="+c.CookieValue)
	cmd.Stdin = os.Stdin
	cmd.Stdout = stdout_w
	cmd.Stderr = stderr_w
	if err := cmd.Start(); err != nil {
		return 1, err
	}

	// Listen to signals and capture them forever. We allow the child
	// process to handle them in some way.
	sigCh := make(chan os.Signal)
	signal.Notify(sigCh, os.Interrupt)
	go func() {
		defer signal.Stop(sigCh)
		for {
			select {
			case <-doneCh:
				return
			case <-sigCh:
			}
		}
	}()

	if err := cmd.Wait(); err != nil {
		exitErr, ok := err.(*exec.ExitError)
		if !ok {
			// This is some other kind of subprocessing error.
			return 1, err
		}

		exitStatus := 1
		if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
			exitStatus = status.ExitStatus()
		}

		// Close the writer end so that the tracker goroutine ends at some point
		stderr_w.Close()

		// Wait on the panic data
		panicTxt := <-panicCh
		if panicTxt != "" {
			if !c.HidePanic {
				c.Writer.Write([]byte(panicTxt))
			}

			c.Handler(panicTxt)
		}

		return exitStatus, nil
	}

	return 0, nil
}
예제 #9
0
파일: updater.go 프로젝트: catalyzeio/cli
func (u *Updater) getExecRelativeDir(dir string) string {
	filename, _ := osext.Executable()
	path := filepath.Join(filepath.Dir(filename), dir)
	return path
}