Ejemplo n.º 1
0
// guessAndLoadPrivateKey takes a path to a public key and determines if a
// private key exists by just stripping ".pub" from the end of it. if so,
// it attempts to load that key into the agent.
func guessAndLoadPrivateKey(ui ui.Ui, pubKeyPath string) (bool, error) {
	fullPath, err := homedir.Expand(pubKeyPath)
	if err != nil {
		return false, err
	}
	if !strings.HasSuffix(fullPath, ".pub") {
		return false, fmt.Errorf("No .pub suffix, cannot guess path.")
	}
	privKeyGuess := strings.TrimSuffix(fullPath, ".pub")
	if _, err := os.Stat(privKeyGuess); os.IsNotExist(err) {
		return false, fmt.Errorf("No file at guessed path.")
	}

	ui.Header("Loading key into SSH Agent")
	ui.Message(fmt.Sprintf(
		"The key you provided (%s) was not found in your SSH Agent.", pubKeyPath))
	ui.Message(fmt.Sprintf(
		"However, Otto found a private key here: %s", privKeyGuess))
	ui.Message(fmt.Sprintf(
		"Automatically running 'ssh-add %s'.", privKeyGuess))
	ui.Message("If your SSH key has a passphrase, you will be prompted for it.")
	ui.Message("")

	if err := sshagent.Add(ui, privKeyGuess); err != nil {
		return false, err
	}

	return true, nil
}
Ejemplo n.º 2
0
// guestAndLoadPrivateKey 获得private key路径,只是依赖判断去除.pub部分的内容
// 如果存在则直接装在agent
func guestAndLoadPrivateKey(ui ui.Ui, pubKeyPath string) (bool, error) {
	fullPath, err := homedir.Expand(pubKeyPath)
	if err != nil {
		return false, err
	}
	if !strings.HasSuffix(fullPath, ".pub") {
		return false, fmt.Errorf("没有找到.pub后缀的文件")
	}
	privKeyGuess := strings.TrimSuffix(fullPath, ".pub")
	if _, err := os.Stat(privKeyGuess); os.IsNotExist(err) {
		return false, fmt.Errorf("文件不存在!")
	}

	ui.Header("装载key到SSH Agent")
	ui.Message(fmt.Sprintf(
		"在SSH Agent中没有你提供的key (%s)", pubKeyPath))
	ui.Message(fmt.Sprintf(
		"然而,Otto在这里:%s 找的了一个private key", privKeyGuess))
	ui.Message(fmt.Sprintf(
		"自动运行'ssh-add %s'.", privKeyGuess))
	ui.Message("如果你的SSH key有密码,你会看到如下提示")
	ui.Message("")

	if err := sshagent.Add(ui, privKeyGuess); err != nil {
		return false, err
	}

	return true, nil
}
Ejemplo n.º 3
0
func (c *CompileCommand) compileCallback(ui ui.Ui) func(appfile.CompileEvent) {
	return func(raw appfile.CompileEvent) {
		switch e := raw.(type) {
		case *appfile.CompileEventDep:
			ui.Message(fmt.Sprintf(
				"Fetching dependency: %s", e.Source))
		case *appfile.CompileEventImport:
			ui.Message(fmt.Sprintf(
				"Fetching import: %s", e.Source))
		}
	}
}
Ejemplo n.º 4
0
// Run runs the given command and streams all the output to the
// given UI. It also connects stdin properly so that input works as
// expected.
func Run(uiVal ui.Ui, cmd *exec.Cmd) error {
	out_r, out_w := io.Pipe()
	cmd.Stdin = os.Stdin
	cmd.Stdout = out_w
	cmd.Stderr = out_w

	// Copy output to the UI until we can't.
	output := false
	uiDone := make(chan struct{})
	go func() {
		defer close(uiDone)
		var buf [1024]byte
		for {
			n, err := out_r.Read(buf[:])
			if n > 0 {
				output = true
				uiVal.Raw(string(buf[:n]))
			}

			// We just break on any error. io.EOF is not an error and
			// is our true exit case, but any other error we don't really
			// handle here. It probably means something went wrong
			// somewhere else anyways.
			if err != nil {
				break
			}
		}
	}()

	// Run the command
	log.Printf("[DEBUG] execDir: %s", cmd.Dir)
	log.Printf("[DEBUG] exec: %s %s", cmd.Path, strings.Join(cmd.Args[1:], " "))

	// Build a runnable command that we can log out to make things easier
	// for debugging. This lets debuging devs just copy and paste the command.
	logRunnableCommand(cmd)

	// Run
	err := Runner(cmd)

	// Wait for all the output to finish
	out_w.Close()
	<-uiDone

	if output {
		// Output one extra newline to separate output from Otto. We only
		// do this if there was any output to begin with.
		uiVal.Message("")
	}

	// Return the output from the command
	return err
}
Ejemplo n.º 5
0
func VerifyCreds(ui ui.Ui, publicKeyPath string) error {
	found, err := HasKey(publicKeyPath)
	if err != nil {
		return SshAgentError(err)
	}
	if !found {
		ok, _ := GuessAndLoadPrivateKey(
			ui, publicKeyPath)
		if ok {
			ui.Message(
				"A private key was found and loaded. Otto will now check\n" +
					"the SSH Agent again and continue if the correct key is loaded")

			found, err = HasKey(publicKeyPath)
			if err != nil {
				return SshAgentError(err)
			}
		}
	}

	if !found {
		return SshAgentError(fmt.Errorf(
			"You specified an SSH public key of: %q, but the private key from this\n"+
				"keypair is not loaded the SSH Agent. To load it, run:\n\n"+
				"  ssh-add [PATH_TO_PRIVATE_KEY]",
			publicKeyPath))
	}
	return nil
}
Ejemplo n.º 6
0
// Run runs the given command and streams all the output to the
// given UI. It also connects stdin properly so that input works as
// expected.
func Run(uiVal ui.Ui, cmd *exec.Cmd) error {
	out_r, out_w := io.Pipe()
	cmd.Stdin = os.Stdin
	cmd.Stdout = out_w
	cmd.Stderr = out_w

	// Copy output to the UI until we can't.
	uiDone := make(chan struct{})
	go func() {
		defer close(uiDone)
		var buf [1024]byte
		for {
			n, err := out_r.Read(buf[:])
			if n > 0 {
				uiVal.Raw(string(buf[:n]))
			}

			// We just break on any error. io.EOF is not an error and
			// is our true exit case, but any other error we don't really
			// handle here. It probably means something went wrong
			// somewhere else anyways.
			if err != nil {
				break
			}
		}
	}()

	// Run the command
	log.Printf("[DEBUG] execDir: %s", cmd.Dir)
	log.Printf("[DEBUG] exec: %s %s", cmd.Path, strings.Join(cmd.Args[1:], " "))
	err := cmd.Run()

	// Wait for all the output to finish
	out_w.Close()
	<-uiDone

	// Output one extra newline to separate output from Otto
	uiVal.Message("")

	// Return the output from the command
	return err
}