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