braintree / runbook

A framework for gradual system automation
MIT License
730 stars 43 forks source link

cd exit status: 127 (SSHKit::Command::Failed) #28

Closed pitosalas closed 4 years ago

pitosalas commented 4 years ago

Why would a simple command "cd" fail: cd exit status: 127 (SSHKit::Command::Failed)

!/usr/bin/env ruby

require "runbook"

Runbook.book "Soa Demo" do
  server "rails@12.12.12.12"

  section "check status" do
    step "uptime" do
      command "uptime"
      command "pwd"
    end

    step "git cd" do
      command "cd soa_demo"
    end

    step "ls and pull" do
      command "ls"
      command "git pull"
    end
  end
end

It works exactly right from ssh:

ssh rails@12.12.12.12
Last login: Sat Feb  8 17:11:11 2020 from 24.12.12.12
rails@ruby-rails-s-1vcpu-1gb-nyc3-01:~$ cd soa_demo
rails@ruby-rails-s-1vcpu-1gb-nyc3-01:~/soa_demo$
pblesi commented 4 years ago

The issue is that cd is a shell built-in but runbook will split the string to invoke the first part as a binary to be executed and the second to be arguments to the binary.

Two options, (1) Use the path setter: https://github.com/braintree/runbook#setters, or (2) you could pass raw: true which will invoke the command using a shell. Note that if you pass raw: true all setters besides the host will not apply to the command.

pitosalas commented 4 years ago

Thanks, that makes sense. But cd is a built-in so what path would I be setting? I came across this possibility which gives an error "Directory does not exist", but it does!

  section "check status" do
    step "git pull" do
      path "/home/rails/soa_demo"
      command "git pull"
    end

I also tried: command "cd /home/rails/soa_demo; git pull", raw: true Which seems to work. but as you say it defeats the other setters - I am not sure what that means. The setter I have at the "Runbook" level (server "xxx") seems to apply to the nested section>step>command even with raw.

Thanks for being so helpful!

pblesi commented 4 years ago

path designates the current working directory that the commands will be executed from. Specifying absolute paths for your commands and arguments is another option. It is surprising that it says the directory does not exist. Maybe that is on a different host? You could try to mkdir -p <the path> in a step before you reference that path in a path setter to ensure it exists.

If you specify raw: true, specifically path, user, group, env, and umask will have no effect on the command.

server and servers will continue to apply to all commands nested under the step or section where the servers are specified.

pitosalas commented 4 years ago

Thanks!