Git Product home page Git Product logo

runbook's People

Contributors

brafales avatar braintree-security avatar braintreeps avatar celeen avatar coopergillan avatar fwolfst avatar highmileage avatar jcambass avatar kjellm avatar lyang avatar onk avatar pblesi avatar voodoologic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

runbook's Issues

A python equivalent

This is more an inquiry than an issue. I read the 'do nothing automation' blog post and really like the idea. This implementation looks really awesome; kudos!

In the process of developing it, has anyone seen a python implementation? I work in a mostly python shop, so I'm avoiding reinventing the wheel. I may be up for maintaining a port, though.

tty-prompt in gemspec seems to be out of date

When I bundle install after putting runbook in my gemfile, I get the following

 Bundler could not find compatible versions for gem "tty-prompt":
 In snapshot (Gemfile.lock):
  tty-prompt (= 0.19.0)

 In Gemfile:
   tty-prompt

   runbook was resolved to 0.13.0, which depends on
     tty-prompt (~> 0.16.0)

I could revert to 0.16.0 of tty-prompt but that is more than a year older than the latest version.

Maintained repo or alternative

if anybody reads this, is there a maintained fork of runbook anywhere out there?

or does anybody have an alternative?

Ruby 3 compatibility issue? :into keyword in `ask?`

When invoking ask in a runbook which is executed with ruby 3.0 (3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]), following errors are thrown:

/home/felix/.rvm/gems/ruby-3.0.0/gems/runbook-1.0.0/lib/runbook/statements/ask.rb:5:in `initialize': wrong number of arguments (given 2, expected 1; required keyword: into) (ArgumentError)

The invocation seems correct, like ask 'E-Mail-Address of user:', into: 'email' and works in older ruby versions.

I assume this has to do with how keyword arguments are handled in ruby 3.

Other specs also do not pass with ruby 3 (and manually loosened bundler constraint).

E.g. a similar case as for the "ask" case fails like this:

34) Runbook::Runner shared variables capture_all command captures cmd on all hosts
      Failure/Error:
        def initialize(cmd, into:, ssh_config: nil, raw: false, strip: true)
          @cmd = cmd
          @into = into
          @ssh_config = ssh_config
          @raw = raw
          @strip = strip
        end
      
      ArgumentError:
        wrong number of arguments (given 2, expected 1; required keyword: into)
      # ./lib/runbook/statements/capture_all.rb:5:in `initialize'
      # ./lib/runbook/extensions/statements.rb:6:in `new'
      # ./lib/runbook/extensions/statements.rb:6:in `method_missing'
      # ./spec/runner_spec.rb:1036:in `block (7 levels) in <top (required)>'
      # ./lib/runbook/extensions/steps.rb:16:in `instance_eval'
      # ./lib/runbook/extensions/steps.rb:16:in `block in step'
      # <internal:kernel>:90:in `tap'
      # ./lib/runbook/extensions/steps.rb:14:in `step'
      # ./spec/runner_spec.rb:1033:in `block (6 levels) in <top (required)>'
      # ./lib/runbook/extensions/sections.rb:11:in `instance_eval'
      # ./lib/runbook/extensions/sections.rb:11:in `block in section'
      # <internal:kernel>:90:in `tap'
      # ./lib/runbook/extensions/sections.rb:9:in `section'
      # ./spec/runner_spec.rb:1032:in `block (5 levels) in <top (required)>'
      # ./lib/runbook.rb:96:in `instance_eval'
      # ./lib/runbook.rb:96:in `block in book'
      # <internal:kernel>:90:in `tap'
      # ./lib/runbook.rb:95:in `book'
      # ./spec/runner_spec.rb:1031:in `block (4 levels) in <top (required)>'
      # ./spec/runner_spec.rb:30:in `block (2 levels) in <top (required)>'
      # ./spec/runner_spec.rb:1060:in `block (4 levels) in <top (required)>'
      # /home/felix/.rvm/gems/ruby-3.0.0/gems/aruba-0.14.14/lib/aruba/rspec.rb:22:in `block (2 levels) in <top (required)>'

Jump to specific Position doesn't check input

Using j to Jump to the specified position and just hitting the enter key after that leads to an exception.


#<Thread:0x000000011c8fa878 /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
        26: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
        25: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:31:in `run'
        24: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:31:in `instance_exec'
        23: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `block (2 levels) in with_ssh_config'
        22: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `instance_exec'
        21: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `block in _with_block'
        20: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `instance_exec'
        19: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:127:in `block in _within_block'
        18: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:86:in `within'
        17: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:80:in `execute'
        16: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `create_command_and_execute'
        15: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `tap'
        14: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `block in create_command_and_execute'
        13: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/netssh.rb:130:in `execute_command'
        12: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/netssh.rb:177:in `with_ssh'
        11: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/connection_pool.rb:63:in `with'
        10: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/connection_pool.rb:63:in `call'
         9: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh.rb:250:in `start'
         8: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh.rb:250:in `new'
         7: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh/transport/session.rb:72:in `initialize'
         6: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:632:in `tcp'
         5: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:227:in `foreach'
         4: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:227:in `each'
         3: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:642:in `block in tcp'
         2: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:137:in `connect'
         1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:64:in `connect_internal'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:64:in `connect': Connection refused - connect(2) for [::1]:22 (Errno::ECONNREFUSED)
        1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing on host localhost: Connection refused - connect(2) for [::1]:22 (SSHKit::Runner::ExecuteError)
Traceback (most recent call last):
        26: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
        25: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:31:in `run'
        24: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:31:in `instance_exec'
        23: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `block (2 levels) in with_ssh_config'
        22: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `instance_exec'
        21: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `block in _with_block'
        20: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `instance_exec'
        19: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/helpers/ssh_kit_helper.rb:127:in `block in _within_block'
        18: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:86:in `within'
        17: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:80:in `execute'
        16: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `create_command_and_execute'
        15: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `tap'
        14: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/abstract.rb:148:in `block in create_command_and_execute'
        13: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/netssh.rb:130:in `execute_command'
        12: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/netssh.rb:177:in `with_ssh'
        11: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/connection_pool.rb:63:in `with'
        10: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/backends/connection_pool.rb:63:in `call'
         9: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh.rb:250:in `start'
         8: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh.rb:250:in `new'
         7: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/net-ssh-7.0.1/lib/net/ssh/transport/session.rb:72:in `initialize'
         6: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:632:in `tcp'
         5: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:227:in `foreach'
         4: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:227:in `each'
         3: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:642:in `block in tcp'
         2: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:137:in `connect'
         1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:64:in `connect_internal'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/2.7.0/socket.rb:64:in `connect': Connection refused - connect(2) for [::1]:22 (Errno::ECONNREFUSED)
        1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing on host localhost: Connection refused - connect(2) for [::1]:22 (SSHKit::Runner::ExecuteError)

๐Ÿ”Œ  โšก๏ธ  in <REDACTED>/ on main 
โ€บ runbook exec xy.rb
Previous position detected: 1.1
Do you want to resume at this position? Yes
Repo file /var/folders/98/t_7cht6n2kvdczf7m8v23kmm0000gn/T/runbook_data_jcambass_xy.yml detected. Loading previous state...
Executing XY...

Description:
    This is a test

Step 1.1: Test

Continue? Jump to the specified position
What position would you like to jump to? 
nil versions are discouraged and will be deprecated in Rubygems 4
Traceback (most recent call last):
        25: from /Users/jcambass/.asdf/installs/ruby/2.7.6/bin/runbook:23:in `<main>'
        24: from /Users/jcambass/.asdf/installs/ruby/2.7.6/bin/runbook:23:in `load'
        23: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/exe/runbook:5:in `<top (required)>'
        22: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
        21: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
        20: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
        19: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
        18: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/cli.rb:59:in `exec'
        17: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/runner.rb:42:in `run'
        16: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:55:in `run'
        15: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/hooks.rb:52:in `invoke_with_hooks'
        14: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/hooks.rb:78:in `_execute_around_hooks'
        13: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/hooks.rb:69:in `block in _execute_around_hooks'
        12: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:58:in `block in run'
        11: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:58:in `loop'
        10: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:59:in `block (2 levels) in run'
         9: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:59:in `each_with_index'
         8: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:59:in `each'
         7: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:63:in `block (3 levels) in run'
         6: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:55:in `run'
         5: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/hooks.rb:50:in `invoke_with_hooks'
         4: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:58:in `block in run'
         3: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:58:in `loop'
         2: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:66:in `block (2 levels) in run'
         1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/entity.rb:126:in `_should_retraverse?'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/run.rb:206:in `start_at_is_substep?': undefined method `start_with?' for nil:NilClass (NoMethodError)

Crash when generating projects with `-`

Generating a project with a - in its name crashes the project generation.

It seems this happens since we're looking for the file my-project/spec/my-project_spec.rb but generated the file my-project/spec/my/project_spec.rb.

โ€บ runbook generate project my-project
         run  bundle gem my-project --test rspec --ci github --rubocop --no-changelog --no-coc --no-mit from "."
Creating gem 'my-project'...
rspec is already configured, ignoring --test flag.
github is already configured, ignoring --ci flag.
RuboCop enabled in config
Initializing git repo in /Users/jcambass/my-project
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: 	git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: 	git branch -m <name>
      create  my-project/Gemfile
      create  my-project/lib/my/project.rb
      create  my-project/lib/my/project/version.rb
      create  my-project/sig/my/project.rbs
      create  my-project/my-project.gemspec
      create  my-project/Rakefile
      create  my-project/README.md
      create  my-project/bin/console
      create  my-project/bin/setup
      create  my-project/.gitignore
      create  my-project/.rspec
      create  my-project/spec/spec_helper.rb
      create  my-project/spec/my/project_spec.rb
      create  my-project/.github/workflows/main.yml
      create  my-project/.rubocop.yml
Gem 'my-project' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html
      remove  my-project/my-project.gemspec
      remove  my-project/README.md
      remove  my-project/Gemfile
      remove  my-project/lib/my-project.rb
      remove  my-project/lib/my-project/version.rb
Where should shared runbook code live?
jectslib/my-project` for runbook-only pro
Use `lib/my-project/runbook` for projects used for non-runbook tasks
d runbook code path: lib/my-project
      create  my-project/README.md
      create  my-project/Gemfile
      create  my-project/lib/my-project.rb
      create  my-project/.ruby-version
      create  my-project/.ruby-gemset
      create  my-project/Runbookfile
      create  my-project/runbooks
      create  my-project/lib/runbook/extensions
      create  my-project/lib/runbook/generators
      create  my-project/lib/my-project
Traceback (most recent call last):
	23: from /Users/jcambass/.asdf/installs/ruby/2.7.6/bin/runbook:23:in `<main>'
	22: from /Users/jcambass/.asdf/installs/ruby/2.7.6/bin/runbook:23:in `load'
	21: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/exe/runbook:5:in `<top (required)>'
	20: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
	19: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	18: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	17: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	16: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor.rb:238:in `block in subcommand'
	15: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:115:in `invoke'
	14: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	13: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	12: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	11: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/generator.rb:34:in `block (2 levels) in <class:Generator>'
	10: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:115:in `invoke'
	 9: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/group.rb:232:in `dispatch'
	 8: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:133:in `invoke_all'
	 7: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:133:in `map'
	 6: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:133:in `each'
	 5: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:133:in `block in invoke_all'
	 4: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	 3: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	 2: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/runbook-1.1.0/lib/runbook/generators/project/project.rb:275:in `remove_bad_test'
	 1: from /Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/actions/file_manipulation.rb:272:in `gsub_file'
/Users/jcambass/.asdf/installs/ruby/2.7.6/lib/ruby/gems/2.7.0/gems/thor-0.20.3/lib/thor/actions/file_manipulation.rb:272:in `binread': No such file or directory @ rb_sysopen - /Users/jcambass/my-project/spec/my-project_spec.rb (Errno::ENOENT)

feature: download directory

Currently download will nicely scp a file. However, directories are not supported (scp -r).
A download_dir statement would be helpful and avoid command "scp -r" or capture %Q{scp -r} calls.

command `curl` doesn't do what I expected

Why is this command giving an error even though it works ok on the command line: command 'curl http://www.rabbitmq.com/rabbitmq-signing-key-public.asc | sudo apt-key add'

tmux_command doesn't seem to respect server

My tmux_command is being executed locally. I want it to first ssh to the server and then execute. How come is that not happening? It seems to defeat the purpose. In other words, it seems like the key use of tmux in this scenario would be to have a pane showing what's happening on server A and another one for server B. Especially if the last step on Server A is a long running process (e.g. httpd) that is handling requests. Or am I thinking of this wrong?

rescue from command Exception

Hello, I'm having a hard time trying to rescue a failed command execution in a meaningful way.

Excerpt from my code:

  section "helm chart" do
    step "Check Helm Chart exists" do
      ruby_command do 
        begin
          command "gsutil ls \"gs://a-helm-repository-bucket/#{app_name}-#{chart_version}.tgz\""
        rescue SSHKit::Command::Failed => e
          puts "Failed", e.inspect
        rescue SSHKit::Runner::ExecuteError => e
          puts "ExecuteError", e.inspect
        rescue => e
          puts "generic exception", e.inspect
        end
      end
      
      confirm "Does the Helm Chart exists?"
    end
  end

The goal of this snippet is to check if a GCP Cloud Storage Bucket Object for a Helm Chart is present, given an application name and a version (taken from user input).

Unfortunately though, I'm not able to rescue the exception in any meaningful way. I tried using raise_on_non_zero_exit but the effect is not what I'd want to achieve.

I'd like to be able to nicely handle known exceptions from this command, by inspecting the exception message and taking appropriate action. As I'm within a ruby_command I was expecting this to work (it should in any case probably?).

Is this even possible? If yes, how could I achieve the expected result? If not, any viable workaround?

Thanks!

Rake isn't a runtime dependency

I started a project as per the installation instructions, and got an exception when running runbook generate runbook:

/Users/rob/.rvm/gems/ruby-2.6.1/gems/airbrussh-1.3.2/lib/airbrussh/rake/context.rb:1:in `require': cannot load such file -- rake (LoadError)

Rake is only listed as a development dependency in the gemspec, but is clearly required at run time. I fixed it by adding Rake to my gemfile, but I guess you might want to fix the gemspec.

Best,
Rob

Conditional steps and menu choices?

I really like the approach of this gem but I'm wondering if there's a way to enable conditional steps or there's a way to present a menu to the user to choice from.

I.e. something like (pseudo code)

optional_step 'Do you want to do this?' do
  # if user choose yes this step is executed
end

choices 'Choose your fruit', from: %w(banana apple) do |f|
  case 'banana'
    ask ...
    command ...
  case 'apple'
    # something else
end

Since you're already using tty-prompt gem you have building blocks for that, so it should be a nice addition to this gem.

feature: output a (remote) command into in a (File::)IO

Scenario is to create tgz archives on a remote server (tar -czf --to-stdout directory).
Currently, captureing the output will be done in memory which is not feasible for large output. Implementation could be specific for files (like capture %Q{tar czf -O}, into_file: 'bigarchive.tgz') or preferrably more general (capture %Q{}, into_io: File.open(...)).

With a bit of headwrapping, this could also be modelled as download_cmd_out tar_cmd, to: 'stdout.file'.

Note that while i refer to tar commands, this might be useful for other commands that produce a lot of data, too.

[question] how to constrain a set of steps to 1 server, before going to the next

Hi,

I'm trying to figure out the proper way to do something like this:

For a list of servers, do ALL the following steps before going to the next server:

  • stop a service
    • verify stopped
  • start a service
    • verify started

If I use a 2 steps, in a section, it will go through the first step for all servers first, then the second step for all servers. But that's not the behavior I'm looking for.

What do you consider the best design pattern for this? Thanks!

Clarification: context of `path`

i'm trying to create a bunch of directories in one step, but have not yet understood what path exactly does.

i've set it once in section context and once in step context, then i shell out inside a ruby_command like so:

step "Create local directory structure" do
  path @clients_dir
  ruby_command do
    command "mkdir -p #{@single_client_dir}/{themes,migration,plugins,migration/#{@domain}}"
  end
end

i expect the directory to be created in @clients_dir but it gets created inside the runbook directory.

is path only the context for ruby commands and not shell commands, i.e. should i do something like FileUtils.makedir_p?

UPDATE: tried that, also does not create the directories in the context of path, but in the cwd of the runbook.

ps: maybe you can activate 'Discussions' for this repo, so this info could get collected in some sort of forum rather than issues.

Ability to set `report_on_exception = false`?

Sometimes, some commands executed on SSH will return an exit status > 0 or output into StdError. In such cases, runbook will throw the SSHKit exception and exits, disallowing the remaining steps to be run.

Is there a way to suppress these known error conditions and continue the runbook execution?
Or is there a way to set report_on_exception = false into the underlying SSHKit config object.

What username is used for ssh?

Even though my runbook says user rails it seems that when the ssh is done it uses my own login name on the controlling computer. I am missing something simple.

#!/usr/bin/env ruby
require "runbook"

runbook = Runbook.book "My First" do
  description "Playing"

  section "SECTION" do
    server "165.227.126.51"
    user "root"
    step "$ ls" do
      note "doing an ls"
      command "ls -la"
    end
  end
end

if __FILE__ == $0
  Runbook::Runner.new(runbook).run
else
  runbook
end

/Users/pitosalas/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/net-ssh-5.2.0/lib/net/ssh.rb:263:in start': Authentication failed for user [email protected] (Net::SSH::AuthenticationFailed)`

can't override system ssh user setting at all

Running on macOS 10.14.5.
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin16]
runbook (0.13.0)

No matter where I set the "user" command, it always falls back to my personal username.

I've tried in the section, step, and using the ssh_command overrides. Still nothing.

Previous step to define server

How can I do so that a previous step can ask me about the server to use

I have tried a series of things with "ask" but it doesn't work, I understand that the server stament is part of the runbook DSL and receives only one string but in what way can I make it modular and save in a variable and then define it, my best try has been the next:

Runbook.book "Restart Nginx" do
  description <<-DESC
This is a simple runbook to restart nginx and verify
it starts successfully
  DESC

target_host = ""

  section "Restart Nginx" do
    step "Define server to restart" do
      ask "Name of server to restart", into: :target_host, default: "localhost", echo: true
      ruby_command do |rb_cmd, metadata, run|
        target_host = rb_cmd.parent.target_host
      end
      wait 5
    end

    server "#{target_host}"
    user "jazb"

    step "Stop Nginx" do
      note "Stopping Nginx..."
      command "whoami"
    end

    step { wait 5 }

    step "Start Nginx" do
      note "Starting Nginx..."
      command "whoami"
      confirm "Nginx is taking traffic?"
      notice "Make sure to report why you restarted nginx"
    end
  end
end

DidYouMean update

Calling `DidYouMean::SPELL_CHECKERS.merge!(error_name => spell_checker)' has been deprecated. Please call `DidYouMean.correct_error(error_name, spell_checker)' instead.

comes up when requiring runbook. probably something in the dependency tree?

tmux_command

I am experimenting with tmux + runbook. Here's a script and an error that it produces. Maybe you can see what's wrong? What does unknown command: C-m mean? It looks like tmux is giving it but I don't know what's going on. Thanks!

#!/usr/bin/env ruby
require "runbook"
require_relative "rbenv"

runbook = Runbook.book "Uneven Layout" do
  layout [[
    {:left => 20, {name: :middle, runbook_pane: true} => 60, :right => 20},
    {bottom_left: 5, bottom_right: 5}
  ]]
  section "Run Primary" do
    step "run" do
      env({TWITTER_CONSUMER_KEY: TWTITER_CONSUMER_KEY,
           TWITTER_CONSUMER_SECRET: TWITTER_CONSUMER_SECRET,
           TWITTER_ACCESS_TOKEN: TWITTER_ACCESS_TOKEN,
           TWITTER_ACCESS_SECRET: TWITTER_ACCESS_SECRET})
      server "rails@" + PRIMARY_SERVER_IP
      tmux_command "pwd", :bottom_right
      tmux_command "/usr/bin/ruby soa_demo/soa_publisher_node.rb;", :bottom_left
    end
  end
end

if __FILE__ == $0
  Runbook::Runner.new(runbook).run(start_at: 1, auto: true)
else
  runbook
end

This produces this output:

~/m/soa_demo (master=) ruby runbook/play.rb
Executing Uneven Layout...

Section 1: Run Primary

Step 1.1: run

unknown command: C-m

Killing all opened tmux panes...
~/m/soa_demo (master *=)

I assumed that the

server "rails@" + PRIMARY_SERVER+IP"

statement would cause the following tmux commands to be sent to that server. Or do I need to actually put an ssh command in the tmux_command itself, like this?

tmux_command 'ssh "rails@" + PRIMARY_SERVER_IP + '/usr/bin/ruby soa_demo/soa_publisher_node.rb;' :bottom_left

Thanks for your help. I'm kind of stuck at this point waiting for your comments!

Long running processes

What's the right way to launch a process that is meant to keep on running? For example, my ruby program is a service that listens on a tcpip port until it is killed. If I start it with a simple command then the runbook blocks. If ^c the runbook then I think the service is left in limbo. This can't be right can it?

p.s. is there a gitter or slack channel on which I can more reasonably post these questions? I know you said it's ok but ...

runbook project generator fails graceless on invalid gem names

When providing a project name that cannot be used as gem name (e.g. starting with numbers), the project generator will print an error but continue to request user input, until it finally fails

runbook generate project 7l
         run  bundle gem 7l --test rspec --no-coc --no-mit from "."
Creating gem '7l'...
Invalid gem name 7l Please give a name which does not start with numbers.
      remove  7l/7l.gemspec
      remove  7l/README.md
      remove  7l/Gemfile
      remove  7l/lib/7l.rb
      remove  7l/lib/7l/version.rb
Where should shared runbook code live?
Use `lib/7l` for runbook-only projects
Use `lib/7l/runbook` for projects used for non-runbook tasks
Shared runbook code path: lib/7l/runbook
      create  7l/README.md
      create  7l/Gemfile
      create  7l/lib/7l.rb
Traceback (most recent call last):
# ...
 1: from /home/void/.rvm/gems/ruby-2.6.1/gems/thor-0.20.3/lib/thor/actions/file_manipulation.rb:272:in `gsub_file'
/home/void/rvm/gems/ruby-2.6.1/gems/thor-0.20.3/lib/thor/actions/file_manipulation.rb:272:in `binread': No such file or directory @ rb_sysopen - /home/void/projects/7l/other/tasks/7l/Rakefile (Errno::ENOENT)

User experience would be improved, if the program fails (statuscode != 0) directly when gem creation fails.

Asserting if something is installed

Hello, I am currently testing out this app of yours and came to a halt with the use case bellow

Usecase: Check if something is installed. If not install, otherwise print a message. Basically, I need to check if there is an executable for something, that means using which executable_name

Problem: which returns non zero exit which then throws a huge error in my face. This is also true for command, type, hash.

Is there a way to handle this or do I need to use try/catch?

The error:

Traceback (most recent call last):
	20: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:12:in `block (2 levels) in execute'
	19: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:29:in `run'
	18: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:29:in `instance_exec'
	17: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `block (2 levels) in with_ssh_config'
	16: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:90:in `instance_exec'
	15: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `block in _with_block'
	14: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:121:in `instance_exec'
	13: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:129:in `block in _within_block'
	12: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:129:in `instance_exec'
	11: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:113:in `block in _as_block'
	10: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/helpers/ssh_kit_helper.rb:113:in `instance_exec'
	 9: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/runbook-0.13.0/lib/runbook/runs/ssh_kit.rb:75:in `block (2 levels) in runbook__statements__capture'
	 8: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:60:in `capture'
	 7: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:141:in `create_command_and_execute'
	 6: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:141:in `tap'
	 5: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/abstract.rb:141:in `block in create_command_and_execute'
	 4: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/local.rb:46:in `execute_command'
	 3: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/open3.rb:101:in `popen3'
	 2: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/open3.rb:219:in `popen_run'
	 1: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/backends/local.rb:64:in `block in execute_command'
/Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/command.rb:99:in `exit_status=': which exit status: 256 (SSHKit::Command::Failed)
which stdout: Nothing written
which stderr: Nothing written
1: from /Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/user/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/sshkit-1.16.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as user@localhost: which exit status: 256 (SSHKit::Runner::ExecuteError)
which stdout: Nothing written
which stderr: Nothing written

Unexpected Behavior: Step Doesn't Skip

@kexline4710 and I ran into what seems like a bug- when going through a runbook, and telling a step to skip, the step then executed. We dug into the code, and found that this unexpected behavior is happening because we have defined a relatively short runbook with steps only- no surrounding sections. This line assumes that a step will have a surrounding section.

I have also run into the restriction before, that while Runbook can nest entities generally, it cannot nest Steps (without using composition). This suggests to me that the tool is designed with the intention that Steps should always have a parent Section.

We propose that either the #gsub in the linked line be changed to accommodate top-level step, or the Runbook library enforce the need for top-level sections more explicitly.

How does "previous position detected" work?

I keep getting this message (while I am just experimenting):

Previous position detected: 1.4
Do you want to resume at this position? (Y/n) 
  1. How is the "previous position detected" work, where is it stored?
  2. If I don't want to be asked, i.e. always begin at first position, how do I do that?

Thanks,

Variable sharing doesn't work for alternate runs

The way that variable sharing is implemented, using a set of hooks on the module, means that alternate runs backends don't get variable sharing without manually registering the hooks themselves.

It doesn't appear to be practical to define the alternate runs backend (in order to be present in Runbook.runs) before the extensions are loaded, because defining a runs backend requires including Runbook::Run. If all the files in runbook required their own dependencies, it would be possible to require "runbook/run", but as all the files in the gem are loaded in lib/runbook.rb, I suspect I would need to replicate two-thirds of that file in order to get Runbook::Run to exist so I could include it.

Incompatibilities to tmux version 3.4

I've just updated from tmux-3.3_a-7-x86_64 to tmux-3.4-3-x86_64 on archlinux, and that seems to break at least the pane-swap integration:

command swap-pane: too many arguments (need at most 0)

and i get two times this error:

size missing

This happens during layout configuration:

  layout [[
    {:left => 1, {name: :right, runbook_pane: true} => 2},
    {bottom: 1}
  ]]

"Unable to retrieve source code" when using Runbook::Viewer

I want to create and save markdown-rendered versions of my runbook.
The runbook is defined in it/add_ldap_user.rb. Running runbook view it/it/add_ldap_user.rb works fine, but if I use md = Runbook::Viewer.new(eval(File.read book)).generate(view: :markdown) (where book is 'it/add_ldap_user.rb`) the markdown output contains "Unable to retrieve source code" instead of the relevant Ruby Code.

The project can be found here (last file in the commit is the relevant source)
ecovillage/operations@6c2dd14 .

Now, I could easily fire up the runbook view commands, but I thought there might be a bug hidden here. Alternatively it could have something to do with the load path and stuff. ./require 'it/add_ldap_user' in the file worked but didnt help.

Add support for Ruby 3.1

#54 originally attempted to add support for Ruby 3.1, but the build failed with some test failures.

This should be investigated separately and the builds should be run for Ruby 3.1 when the specs all pass.

Skip step

It would be nice to be able to temporarily skip step. For example, great solution is to add x prefix or add :skip argument to step, as implemented in rspec
If you think this is a great idea, I would gladly send PR, with implementation this feature.

Allow 'ask' to be run at "compile" time

For semi-automated runbooks, it is useful to be able to collect all the necessary information that is needed by a runbook up-front, before the steps start executing. In the simple case, you can just ask all your questions in the first step, but if you're aggregating multiple sections or runbooks together into one mega runbook o' doom, and each of the components has questions of its own, you end up having to come back to the run all the time to answer more questions. If I could answer all the questions at once, and then wander off to get a cuppa while the runbook does its thing, I would be a much happier (and well-caffeinated) person.

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

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 "[email protected]"

  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 [email protected]
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$

Best practices

I'm looking for more examples than are in github so I can learn best practices with runbook. For example, I assume that there's one runbook for each of my goals/tasks/objectives whatever you want to call them? So I might have runbook exec initialize_servers, runbook exec restart_servers etc.? Is there a resource where I can read about that? (Assume that I've read the doc page fully even though I've actually jumped around and might have missed it right there :)

Dealing with errors

What if the command fails?

Exception while executing as [email protected]: git exit status: 128 (SSHKit::Runner::ExecuteError)
git stdout: Nothing written
git stderr: fatal: destination path 'soa_demo' already exists and is not an empty directory. 

What's the recommended way to handle this situation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.