runbook 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +129 -23
- data/TODO.md +10 -2
- data/lib/runbook/cli.rb +31 -21
- data/lib/runbook/cli_base.rb +38 -0
- data/lib/runbook/generator.rb +38 -0
- data/lib/runbook/generators/base.rb +45 -0
- data/lib/runbook/generators/dsl_extension/dsl_extension.rb +29 -0
- data/lib/runbook/generators/dsl_extension/templates/dsl_extension.tt +25 -0
- data/lib/runbook/generators/generator/generator.rb +43 -0
- data/lib/runbook/generators/generator/templates/generator.tt +53 -0
- data/lib/runbook/generators/project/project.rb +278 -0
- data/lib/runbook/generators/project/templates/Gemfile.tt +6 -0
- data/lib/runbook/generators/project/templates/README.md.tt +29 -0
- data/lib/runbook/generators/project/templates/Runbookfile.tt +11 -0
- data/lib/runbook/generators/project/templates/base_file.rb.tt +8 -0
- data/lib/runbook/generators/runbook/runbook.rb +22 -0
- data/lib/runbook/generators/runbook/templates/runbook.tt +20 -0
- data/lib/runbook/generators/statement/statement.rb +18 -0
- data/lib/runbook/generators/statement/templates/statement.tt +34 -0
- data/lib/runbook/installer.rb +85 -0
- data/lib/runbook/util/runbook.rb +4 -0
- data/lib/runbook/version.rb +1 -1
- data/lib/runbook.rb +8 -0
- data/runbook.gemspec +3 -2
- metadata +24 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fe4b7ea15d7d74edf1a660fda55c9f8360a16f7e5032acadc427039240b9cf6
|
4
|
+
data.tar.gz: c72e2c91cd75587c87ed4b9e5921e1be050ea6466c59e1d903fefcf7f6770bfd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 129f995881810339793273c74d00a872b62cd865f8712fe7db063356c95bdae7f090537d244383b00fbf81cf2de8555e59627248b9e4a6284320aa9594508ef1
|
7
|
+
data.tar.gz: b1c2ef5526b2225d02a246c2d4f5d8e657c599ab04faf96f192084ea4f11d61863f455abc91136a17174dd7645f1112231fa7614ed83862d4444debbc0d2ca07
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,21 @@ This log maintains a list of all substantive changes to Runbook. The log include
|
|
4
4
|
|
5
5
|
## master
|
6
6
|
|
7
|
+
## `v0.13.0` (2019-07-10)
|
8
|
+
|
9
|
+
### Potentially Breaking Changes:
|
10
|
+
|
11
|
+
* Uses of Runbook that expect the CLI to return a zero exit code may exhibit different behavior if their runbook encounters an error.
|
12
|
+
|
13
|
+
### Fixes:
|
14
|
+
|
15
|
+
* Return non-zero exit code on CLI error
|
16
|
+
|
17
|
+
### New Features
|
18
|
+
|
19
|
+
* Add runbook "generate" command, including generator, runbook, statement, dsl_extension, and project generators
|
20
|
+
* Add "install" CLI command
|
21
|
+
|
7
22
|
## `v0.12.1` (2019-06-12)
|
8
23
|
|
9
24
|
### Fixes:
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Runbook
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/runbook.svg)](https://badge.fury.io/rb/runbook)
|
4
4
|
|
5
5
|
Runbook provides a DSL for specifying a series of steps to execute an operation. Once your runbook is specified, you can use it to generate a formatted representation of the book or to execute the runbook interactively. For example, you can export your runbook to markdown or use the same runbook to execute commands on remote servers.
|
6
6
|
|
@@ -9,14 +9,14 @@ Runbook provides a DSL for specifying a series of steps to execute an operation.
|
|
9
9
|
</div>
|
10
10
|
<br>
|
11
11
|
|
12
|
-
Runbook
|
12
|
+
Runbook has two modes for evaluating your runbook. The first mode, view mode, allows you to export your runbook into various formats such as markdown. The second mode, run mode, allows you to execute behavior based on the statements in your runbook.
|
13
13
|
|
14
14
|
<div align="center">
|
15
15
|
<img width="600" src="images/runbook_execution_modes.png" alt="diagram of execution modes" />
|
16
16
|
</div>
|
17
17
|
<br>
|
18
18
|
|
19
|
-
Runbook
|
19
|
+
Runbook can be integrated into existing infrastructure in many different ways. It can be integrated into existing projects to add orchestration functionality, installed on systems as a stand-alone executable, or runbooks can be defined as self-executable scripts. In addition to being useful for automating common tasks, runbooks are a perfect bridge for providing operations teams with step-by-step instructions to handle common issues (especially when solutions cannot be easily automated).
|
20
20
|
|
21
21
|
Lastly, Runbook provides an extendable interface for augmenting the DSL and defining your own behavior.
|
22
22
|
|
@@ -28,15 +28,18 @@ Lastly, Runbook provides an extendable interface for augmenting the DSL and defi
|
|
28
28
|
* **Noop and Auto Modes** - Runbooks can be executed in noop mode. This allows you to see what a runbook will do before it executes. Runbooks can be run in auto mode to eliminate the need for human interaction.
|
29
29
|
* **Execution Lifecycle Hooks** - Runbook provides before, after, around hooks to augment its execution behavior.
|
30
30
|
* **Tmux Integration** - Runbook integrates with [tmux](https://github.com/tmux/tmux). You can define terminal pane layouts and send commands to terminal panes.
|
31
|
+
* **Generators** - Runbook provides commands to generate runbooks, extensions, and runbook projects. You can define your own generators for easy, customized runbook creation.
|
31
32
|
* **Extendable DSL** - Runbook's DSL is designed to be extendable. You can extend its DSL to add your own behavior.
|
32
33
|
|
33
34
|
## Use Cases
|
34
35
|
|
35
|
-
|
36
|
+
Though Runbook can solve a myriad of problems, it is best used for removing the need for repeated, rote developer operations. Runbook allows developers to execute processes at a higher level than that of individual command-line commands. Additionally, Runbook provides features to simply and safely execute operations in mission-critical environments.
|
36
37
|
|
37
38
|
Runbook is not intended to replace more special-purpose automation solutions such as configuration management solutions (Puppet, Chef, Ansible, Salt), deployment solutions (Capistrano, Kubernetes, Docker Swarm), monitoring solutions (Nagios, Datadog), or local command execution (shell scripts, Rake tasks, Make). Instead Runbook is best used as a glue when needing to accomplish a task that cuts across these domains.
|
38
39
|
|
39
|
-
##
|
40
|
+
## Quick Start
|
41
|
+
|
42
|
+
### Installation
|
40
43
|
|
41
44
|
Add this line to your application's Gemfile:
|
42
45
|
|
@@ -52,6 +55,62 @@ Or install it yourself as:
|
|
52
55
|
|
53
56
|
$ gem install runbook
|
54
57
|
|
58
|
+
### Your First Runbook
|
59
|
+
|
60
|
+
Generate a runbook using the Runbook Generator:
|
61
|
+
|
62
|
+
$ runbook generate runbook my_first_runbook
|
63
|
+
|
64
|
+
Execute the runbook:
|
65
|
+
|
66
|
+
$ runbook exec my_first_runbook.rb
|
67
|
+
|
68
|
+
## Slightly Longer Start
|
69
|
+
|
70
|
+
When setting up Runbook, you can install it at a system level, create a dedicated runbook project, or incorporate Runbook into an existing project.
|
71
|
+
|
72
|
+
### System Level Setup
|
73
|
+
|
74
|
+
Install runbook at a system level using `gem`:
|
75
|
+
|
76
|
+
$ gem install runbook
|
77
|
+
|
78
|
+
Set any Runbook [configuration](#configuration) in `/etc/runbook.conf`.
|
79
|
+
|
80
|
+
Generate runbook files using `runbook generate runbook`. Execute `runbook generate help runbook` for more details.
|
81
|
+
|
82
|
+
Installing Runbook at a system level can be useful for executing runbooks on remote hosts or within docker containers. One disadvantage of installing Runbook at a system level is that there is no built-in solution for dependency management.
|
83
|
+
|
84
|
+
### New Project Setup
|
85
|
+
|
86
|
+
Install runbook using `gem`:
|
87
|
+
|
88
|
+
$ gem install runbook
|
89
|
+
|
90
|
+
Generate a new runbook project:
|
91
|
+
|
92
|
+
$ runbook generate project <PROJECT_NAME>
|
93
|
+
|
94
|
+
This will generate a new runbook project. Cd into your project directory and initialize its dependencies:
|
95
|
+
|
96
|
+
$ cd <PROJECT_NAME> && bin/setup
|
97
|
+
|
98
|
+
### Existing Project Setup
|
99
|
+
|
100
|
+
Add this line to your project's Gemfile:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
gem 'runbook'
|
104
|
+
```
|
105
|
+
|
106
|
+
Install the Runbook gem:
|
107
|
+
|
108
|
+
$ bundle install
|
109
|
+
|
110
|
+
Install Runbook into your project:
|
111
|
+
|
112
|
+
$ bundle exec runbook install
|
113
|
+
|
55
114
|
## Contents
|
56
115
|
|
57
116
|
* [1. Runbook Anatomy](#runbook-anatomy)
|
@@ -92,21 +151,24 @@ Or install it yourself as:
|
|
92
151
|
* [4.5 Deep Nesting](#deep-nesting)
|
93
152
|
* [4.6 Load Vs. Eval](#load-vs-eval)
|
94
153
|
* [4.7 Passing State](#passing-state)
|
95
|
-
* [5.
|
96
|
-
* [5.1
|
97
|
-
* [5.2
|
98
|
-
|
99
|
-
* [
|
100
|
-
* [
|
101
|
-
* [
|
102
|
-
* [
|
103
|
-
* [5
|
104
|
-
* [6.
|
105
|
-
* [7
|
106
|
-
* [8
|
107
|
-
* [
|
108
|
-
* [
|
109
|
-
* [
|
154
|
+
* [5. Generators](#generators)
|
155
|
+
* [5.1 Predefined Generators](#predefined-generators)
|
156
|
+
* [5.2 Custom Generators](#custom-generators)
|
157
|
+
* [6. Extending Runbook](#extending-runbook)
|
158
|
+
* [6.1 Adding Runs and Views](#adding-runs-and-views)
|
159
|
+
* [6.2 DSL Extensions](#dsl-extensions)
|
160
|
+
* [6.3 Adding New Statements](#adding-new-statements)
|
161
|
+
* [6.4 Adding Run and View Functionality](#adding-run-and-view-functionality)
|
162
|
+
* [6.5 Augmenting Functionality With Hooks](#augmenting-functionality-with-hooks)
|
163
|
+
* [6.6 Adding New Run Behaviors](#adding-new-run-behaviors)
|
164
|
+
* [6.7 Adding to Runbook's Run Metadata](#adding-to-runbooks-run-metadata)
|
165
|
+
* [6.8 Adding to Runbook's Configuration](#adding-to-runbooks-configuration)
|
166
|
+
* [7. Known Issues](#known-issues)
|
167
|
+
* [8. Development](#development)
|
168
|
+
* [9. Contributing](#contributing)
|
169
|
+
* [10. Feature Requests](#feature-requests)
|
170
|
+
* [11. License](#license)
|
171
|
+
* [12. Code of Conduct](#code-of-conduct)
|
110
172
|
|
111
173
|
## Runbook Anatomy
|
112
174
|
|
@@ -496,7 +558,7 @@ If the `ssh_kit` configuration looks familiar, that's because it's an SSHKit Con
|
|
496
558
|
|
497
559
|
### Configuration Files
|
498
560
|
|
499
|
-
Runbook
|
561
|
+
Runbook loads configuration from a number of predefined files. Runbook will attempt to load configuration from the following locations on startup: `/etc/runbook.conf`, a `Runbookfile` in a parent directory from the current directory, a `.runbook.conf` file in the current user's home directory, a file specified with `--config` on the command line, any configuration specified in a runbook. Runbook will also load configuration from these files in this order of preference, respectively. That is, configuration values specified at the project level (`Runbookfile`) will override configuration values set at the global level (`/etc/runbook.conf`), etc.
|
500
562
|
|
501
563
|
## Working With Runbooks
|
502
564
|
|
@@ -617,7 +679,7 @@ The following are best practices when developing your own runbooks.
|
|
617
679
|
|
618
680
|
### Iterative Automation
|
619
681
|
|
620
|
-
Runbooks allow for a
|
682
|
+
Runbooks allow for a gradual transition from entirely manual operations to full automation. Runbooks can start out as a simple outline of all steps required to carry out an operation. From there, commands and prompts can be added to the runbook, actually carrying out and replacing the manual processes.
|
621
683
|
|
622
684
|
Monitoring can transition from a process required by a human into something that can be codified and executed by your runbook. Eventually, the runner's `auto` flag can be used to allow the runbook to run uninterrupted without any human intervention. These runbooks can be triggered automatically in response to detected events. This will allow you to do more important things with your time, like eat ice cream.
|
623
685
|
|
@@ -739,6 +801,50 @@ Instance variables are only passed between statements such as `ruby_command`. Th
|
|
739
801
|
|
740
802
|
Be careful with your naming of instance variables as it is possible to clobber the step's DSL methods because they share the same namespace.
|
741
803
|
|
804
|
+
## Generators
|
805
|
+
|
806
|
+
Runbook provides a number of generators accessible via the command line that can be used to generate code for new runbooks, Runbook projects, and Runbook extensions. Additionally, Runbook provides a generator generator so you can define your own custom generators.
|
807
|
+
|
808
|
+
### Predefined Generators
|
809
|
+
|
810
|
+
Runbook provides a number of predefined generators. You can see the full list using Runbook's command line help.
|
811
|
+
|
812
|
+
$ runbook help generate
|
813
|
+
|
814
|
+
Commands:
|
815
|
+
runbook generate dsl_extension NAME [options] # Generate a dsl_extension for adding custom runbook DSL functionality
|
816
|
+
runbook generate generator NAME [options] # Generate a runbook generator named NAME, e.x. acme_runbook
|
817
|
+
runbook generate help [COMMAND] # Describe subcommands or one specific subcommand
|
818
|
+
runbook generate project NAME [options] # Generate a project for your runbooks
|
819
|
+
runbook generate runbook NAME [options] # Generate a runbook named NAME, e.x. deploy_nginx
|
820
|
+
runbook generate statement NAME [options] # Generate a statement named NAME (e.x. ruby_command) that can be used in your runbooks
|
821
|
+
|
822
|
+
Base options:
|
823
|
+
-c, [--config=CONFIG] # Path to runbook config file
|
824
|
+
[--root=ROOT] # The root directory for your generated code
|
825
|
+
# Default: .
|
826
|
+
|
827
|
+
Runtime options:
|
828
|
+
-f, [--force] # Overwrite files that already exist
|
829
|
+
-p, [--pretend], [--no-pretend] # Run but do not make any changes
|
830
|
+
-q, [--quiet], [--no-quiet] # Suppress status output
|
831
|
+
-s, [--skip], [--no-skip] # Skip files that already exist
|
832
|
+
|
833
|
+
Unless otherwise specified, all `NAME` arguments should be specified in a snake case format (e.x. `acme_runbook`). The `-p/--pretend` flag can be helpful for seeing what files a generator will create before it creates them.
|
834
|
+
|
835
|
+
### Custom Generators
|
836
|
+
|
837
|
+
The generator generator is useful for defining your own custom generators. Runbook uses [Thor Generators](https://github.com/erikhuda/thor/wiki/Generators) in the background, so any functionality you can do using Thor Generators can also be done using Runbook generators.
|
838
|
+
|
839
|
+
Generate your own generator using the `generate generator` command
|
840
|
+
|
841
|
+
$ runbook generate generator my_new_generator --root lib/runbook/generators
|
842
|
+
create my_new_generator
|
843
|
+
create my_new_generator/templates
|
844
|
+
create my_new_generator/my_new_generator.rb
|
845
|
+
|
846
|
+
`my_new_generator/my_new_generator.rb` contains all the logic for generating your new code including arguments, options, and new files. ERB-templated files live in `my_new_generator/templates`. Remember to require your generator file in a runbook config file such as your `Runbookfile` so it can be loaded by the CLI. Generators cannot be required in config files specified at the command line due to the order with which the command line code is loaded. Once loaded, any child classes of `Runbook::Generators` will be included in Runbook's generator CLI.
|
847
|
+
|
742
848
|
## Extending Runbook
|
743
849
|
|
744
850
|
Runbook can be extended to add custom functionality.
|
@@ -800,7 +906,7 @@ module Runbook::Statements
|
|
800
906
|
end
|
801
907
|
```
|
802
908
|
|
803
|
-
In the above example a keyword `diagram` will be
|
909
|
+
In the above example a keyword `diagram` will be added to the step dsl and its arguments will be used to initialize the Diagram object.
|
804
910
|
|
805
911
|
### Adding Run and View Functionality
|
806
912
|
|
data/TODO.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
## Desired feature list
|
2
2
|
* [X] Revise README.md
|
3
|
-
* []
|
4
|
-
* [] Create a generator for a runbook? Allow for custom generators?
|
3
|
+
* [X] Create a generator for a runbook? Allow for custom generators?
|
5
4
|
* Generate runbook templates
|
6
5
|
* Generate runbook projects with Runbookfile, Gemfile, etc.
|
7
6
|
* Generate plugins
|
7
|
+
* [] capistrano-runbook gem that integrates runbook into capistrano tasks
|
8
8
|
* [] Add Appraisal to test against multiple versions of Ruby
|
9
9
|
* [] Update output to be more log friendly, including timestamps for operations
|
10
10
|
* [] Allow for preventing echo when prompting for input
|
@@ -15,11 +15,18 @@
|
|
15
15
|
* [] Replace Thor with a solution that is more easily extendable (adding new flags, etc.)
|
16
16
|
* [] Add goto statements for repeating steps (functionality exists in paranoid mode)
|
17
17
|
* [] Add test statement
|
18
|
+
* [] Add ruby_assert statement
|
18
19
|
* [] Feedback on completion of tmux commands (when they complete, return values, outputs)
|
19
20
|
* [] Add shorter aliases for tmux layout keys
|
20
21
|
* [] Add host aliases for ssh_config setters
|
21
22
|
* [] Allow for step dependencies that get executed before the step
|
22
23
|
* [] Add periodic flush for sshkit output
|
24
|
+
* [] Update assert attribute nomenclature (timeout_statement)
|
25
|
+
* [] Update ssh_kit to count commands separately between steps
|
26
|
+
* [] Create a plugin generator
|
27
|
+
* [] Create generator for a new run (sshkit, etc.)
|
28
|
+
* [] Create generator for a new view (markdown, yaml, html, etc.)
|
29
|
+
* Add rake tasks to generators for viewing and executing runbooks
|
23
30
|
* Add a way to execute a series of commands in groups
|
24
31
|
* Docker testing story for more full-stack integration tests
|
25
32
|
* Test integration with sshkit
|
@@ -34,5 +41,6 @@
|
|
34
41
|
* Can convert from Ruby format to yaml (depending on compatibility) and yaml to Ruby
|
35
42
|
* Guard for view updates (How to handle arguments?)
|
36
43
|
* Be able to serve up markdown docs (web server) for easy viewing
|
44
|
+
* Add interactive executable for all runbooks in a project
|
37
45
|
* Could provide a rake task for compiling and nooping runbooks?
|
38
46
|
* Can specify input-format, output-format, input (file), and output (file)
|
data/lib/runbook/cli.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "runbook"
|
3
|
+
require "runbook/cli_base"
|
4
|
+
require "runbook/installer"
|
5
|
+
|
6
|
+
# Needed to load custom generators
|
7
|
+
Runbook::Configuration.load_config
|
8
|
+
require "runbook/generator"
|
3
9
|
|
4
10
|
module Runbook
|
5
11
|
class CLI < Thor
|
6
|
-
|
7
|
-
class_option :config, aliases: :c, type: :string
|
12
|
+
include ::Runbook::CLIBase
|
8
13
|
|
9
|
-
|
10
|
-
super(args, local_options, config)
|
11
|
-
|
12
|
-
cmd_name = config[:current_command].name
|
13
|
-
_set_cli_config(options[:config], cmd_name) if options[:config]
|
14
|
-
end
|
14
|
+
map "--version" => :__print_version
|
15
15
|
|
16
16
|
desc "view RUNBOOK", "Prints a formatted version of the runbook"
|
17
17
|
long_desc <<-LONGDESC
|
@@ -19,7 +19,7 @@ module Runbook
|
|
19
19
|
|
20
20
|
With --view (-v), Prints the view using the specified view type
|
21
21
|
LONGDESC
|
22
|
-
option :view, aliases:
|
22
|
+
option :view, aliases: "-v", type: :string, default: :markdown
|
23
23
|
def view(runbook)
|
24
24
|
runbook = _retrieve_runbook(runbook, :view)
|
25
25
|
puts Runbook::Viewer.new(runbook).generate(
|
@@ -49,11 +49,11 @@ module Runbook
|
|
49
49
|
With --start-at (-s), Runs the runbook starting at the specified
|
50
50
|
section or step.
|
51
51
|
LONGDESC
|
52
|
-
option :run, aliases:
|
53
|
-
option :noop, aliases:
|
54
|
-
option :auto, aliases:
|
55
|
-
option :"no-paranoid", aliases:
|
56
|
-
option :start_at, aliases:
|
52
|
+
option :run, aliases: "-r", type: :string, default: :ssh_kit
|
53
|
+
option :noop, aliases: "-n", type: :boolean
|
54
|
+
option :auto, aliases: "-a", type: :boolean
|
55
|
+
option :"no-paranoid", aliases: "-P", type: :boolean
|
56
|
+
option :start_at, aliases: "-s", type: :string, default: "0"
|
57
57
|
def exec(runbook)
|
58
58
|
runbook = _retrieve_runbook(runbook, :exec)
|
59
59
|
Runbook::Runner.new(runbook).run(
|
@@ -65,6 +65,23 @@ module Runbook
|
|
65
65
|
)
|
66
66
|
end
|
67
67
|
|
68
|
+
desc "generate GENERATOR", "Generate runbook objects from a template, such as runbooks, projects, or plugins."
|
69
|
+
long_desc <<-LONGDESC
|
70
|
+
Generates a runbook, runbook node, runbook project, or runbook plugin from a template.
|
71
|
+
LONGDESC
|
72
|
+
subcommand "generate", Runbook::Generator
|
73
|
+
|
74
|
+
desc "install", "Install Runbook into an existing project"
|
75
|
+
long_desc "Set up Runbook directory structure and Runbookfile in an existing project for executing runbooks."
|
76
|
+
Runbook::Installer.class_options.values.each do |co|
|
77
|
+
method_option co.name, desc: co.description, required: co.required,
|
78
|
+
default: co.default, aliases: co.aliases, type: co.type,
|
79
|
+
banner: co.banner, hide: co.hide
|
80
|
+
end
|
81
|
+
def install
|
82
|
+
invoke(Runbook::Installer)
|
83
|
+
end
|
84
|
+
|
68
85
|
desc "--version", "Print runbook's version"
|
69
86
|
def __print_version
|
70
87
|
puts "Runbook v#{Runbook::VERSION}"
|
@@ -72,13 +89,6 @@ module Runbook
|
|
72
89
|
|
73
90
|
private
|
74
91
|
|
75
|
-
def _set_cli_config(config, cmd)
|
76
|
-
unless File.exist?(config)
|
77
|
-
raise Thor::InvocationError, "#{cmd}: cannot access #{config}: No such file or directory"
|
78
|
-
end
|
79
|
-
Runbook::Configuration.cli_config_file = config
|
80
|
-
end
|
81
|
-
|
82
92
|
def _retrieve_runbook(runbook, cmd)
|
83
93
|
unless File.exist?(runbook)
|
84
94
|
raise Thor::InvocationError, "#{cmd}: cannot access #{runbook}: No such file or directory"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Runbook::CLIBase
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
|
5
|
+
base.check_unknown_options!
|
6
|
+
|
7
|
+
base.class_option(
|
8
|
+
:config,
|
9
|
+
aliases: "-c",
|
10
|
+
type: :string,
|
11
|
+
group: :base,
|
12
|
+
desc: "Path to runbook config file"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(args = [], local_options = {}, config = {})
|
17
|
+
super(args, local_options, config)
|
18
|
+
|
19
|
+
cmd_name = config[:current_command].name
|
20
|
+
_set_cli_config(options[:config], cmd_name) if options[:config]
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
def exit_on_failure?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def _set_cli_config(config, cmd)
|
32
|
+
unless File.exist?(config)
|
33
|
+
raise Thor::InvocationError, "#{cmd}: cannot access #{config}: No such file or directory"
|
34
|
+
end
|
35
|
+
Runbook::Configuration.cli_config_file = config
|
36
|
+
Runbook::Configuration.reconfigure
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Runbook
|
2
|
+
class Generator < Thor
|
3
|
+
include Runbook::CLIBase
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
Runbook::Generators::Base.set_base_options(self)
|
7
|
+
|
8
|
+
def self._unique_class_options(generator)
|
9
|
+
generator.class_options.values.reject do |class_option|
|
10
|
+
class_option.group == "Runtime" ||
|
11
|
+
class_option.group == "Base"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Runbook.generators.each do |generator|
|
16
|
+
desc(generator.usage, generator.description, generator.options)
|
17
|
+
|
18
|
+
long_desc(generator.long_description)
|
19
|
+
|
20
|
+
_unique_class_options(generator).each do |co|
|
21
|
+
method_option(
|
22
|
+
co.name,
|
23
|
+
desc: co.description,
|
24
|
+
required: co.required,
|
25
|
+
default: co.default,
|
26
|
+
aliases: co.aliases,
|
27
|
+
type: co.type,
|
28
|
+
banner: co.banner,
|
29
|
+
hide: co.hide,
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
define_method(generator.command) do |*args|
|
34
|
+
invoke(generator, args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Runbook::Generators
|
2
|
+
module Base
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
base.include(Thor::Actions)
|
6
|
+
|
7
|
+
set_base_options(base)
|
8
|
+
base.check_unknown_options!
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.set_base_options(base)
|
12
|
+
base.class_option(
|
13
|
+
:root,
|
14
|
+
group: :base,
|
15
|
+
default: ".",
|
16
|
+
desc: "The root directory for your generated code",
|
17
|
+
)
|
18
|
+
base.add_runtime_options!
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def command
|
23
|
+
self.to_s.gsub("Runbook::Generators::", "").underscore
|
24
|
+
end
|
25
|
+
|
26
|
+
def usage
|
27
|
+
args = arguments.map(&:banner).join(" ")
|
28
|
+
args += " " unless args.empty?
|
29
|
+
"#{command} #{args}[options]"
|
30
|
+
end
|
31
|
+
|
32
|
+
def description
|
33
|
+
"Generate a #{command}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def long_description
|
37
|
+
description
|
38
|
+
end
|
39
|
+
|
40
|
+
def options
|
41
|
+
{}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Runbook::Generators
|
2
|
+
class DslExtension < Thor::Group
|
3
|
+
include ::Runbook::Generators::Base
|
4
|
+
|
5
|
+
source_root File.dirname(__FILE__)
|
6
|
+
|
7
|
+
def self.description
|
8
|
+
"Generate a dsl_extension for adding custom runbook DSL functionality"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.long_description
|
12
|
+
<<-LONG_DESC
|
13
|
+
This generator provides a template for extending Runbook's DSL. Using a
|
14
|
+
DSL extension, you can add custom commands to a book, section, or step
|
15
|
+
that can be used in your runbooks.
|
16
|
+
LONG_DESC
|
17
|
+
end
|
18
|
+
|
19
|
+
argument :name, desc: "The name of your dsl_extension, e.x. rollback_section"
|
20
|
+
|
21
|
+
def create_dsl_extension
|
22
|
+
target = File.join(
|
23
|
+
parent_options[:root],
|
24
|
+
"#{name.underscore}.rb",
|
25
|
+
)
|
26
|
+
template('templates/dsl_extension.tt', target)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Remember to require this file in a runbook config file
|
2
|
+
# or in your project so it is available in your runbooks
|
3
|
+
# See https://github.com/braintree/runbook/tree/master/lib/runbook/extensions
|
4
|
+
# for examples of DSL extensions
|
5
|
+
module MyProject::RunbookExtensions
|
6
|
+
module <%= name.classify %>
|
7
|
+
module DSL
|
8
|
+
# def description(msg)
|
9
|
+
# Runbook::Statements::Description.new(msg).tap do |desc|
|
10
|
+
# # All DSLs can reference their parent object using
|
11
|
+
# # the parent method. This allows you to modify the
|
12
|
+
# # parent book, section, or step of the DSL
|
13
|
+
# parent.add(desc)
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Uncomment the below statements to add the the DSL methods to
|
20
|
+
# Book, Section, and Step DSLs respectively. Now this method can
|
21
|
+
# be called from the corresponding DSL in your runbooks
|
22
|
+
# Runbook::Entities::Book::DSL.prepend(<%= name.classify %>::DSL)
|
23
|
+
# Runbook::Entities::Section::DSL.prepend(<%= name.classify %>::DSL)
|
24
|
+
# Runbook::Entities::Step::DSL.prepend(<%= name.classify %>::DSL)
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Runbook::Generators
|
2
|
+
class Generator < Thor::Group
|
3
|
+
include ::Runbook::Generators::Base
|
4
|
+
|
5
|
+
source_root File.dirname(__FILE__)
|
6
|
+
|
7
|
+
def self.usage
|
8
|
+
"generator NAME [options]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.description
|
12
|
+
"Generate a runbook generator named NAME, e.x. acme_runbook"
|
13
|
+
end
|
14
|
+
|
15
|
+
argument :name, desc: "The name of your generator for populating boilerplate"
|
16
|
+
|
17
|
+
def create_generator_directory
|
18
|
+
target = File.join(
|
19
|
+
parent_options[:root],
|
20
|
+
name.underscore,
|
21
|
+
)
|
22
|
+
empty_directory(target)
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_templates_directory
|
26
|
+
target = File.join(
|
27
|
+
parent_options[:root],
|
28
|
+
name.underscore,
|
29
|
+
"templates",
|
30
|
+
)
|
31
|
+
empty_directory(target)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_generator
|
35
|
+
target = File.join(
|
36
|
+
parent_options[:root],
|
37
|
+
name.underscore,
|
38
|
+
"#{name.underscore}.rb",
|
39
|
+
)
|
40
|
+
template('templates/generator.tt', target)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Runbook::Generators
|
2
|
+
# Remember to require this class in a runbook config file such as your
|
3
|
+
# Runbookfile so it can be used from the command line. Note that you cannot
|
4
|
+
# require this generator from a config file specified on the command line.
|
5
|
+
class <%= name.classify %> < Thor::Group
|
6
|
+
include ::Runbook::Generators::Base
|
7
|
+
|
8
|
+
source_root File.dirname(__FILE__)
|
9
|
+
|
10
|
+
# Uncomment this method to customize the generator's usage
|
11
|
+
# description in runbook's help description.
|
12
|
+
#
|
13
|
+
# def self.usage
|
14
|
+
# args = arguments.map(&:banner).join(" ")
|
15
|
+
# args += " " unless args.empty?
|
16
|
+
# "<%= name.underscore %> #{args}[options]"
|
17
|
+
# end
|
18
|
+
|
19
|
+
# Uncomment this method to customize the generator's
|
20
|
+
# description in runbook's help message.
|
21
|
+
#
|
22
|
+
# def self.description
|
23
|
+
# "Generate a <%= name %>"
|
24
|
+
# end
|
25
|
+
|
26
|
+
# Uncomment this method to customize the generator's
|
27
|
+
# long description in runbook's help message.
|
28
|
+
#
|
29
|
+
# def self.long_description
|
30
|
+
# <<-LONG_DESC
|
31
|
+
# Here you can fully describe the options of your generator.
|
32
|
+
# LONG_DESC
|
33
|
+
# end
|
34
|
+
|
35
|
+
# Argument example
|
36
|
+
# argument :name, desc: "The name of your <%= name.underscore %>, e.x. deploy_nginx"
|
37
|
+
|
38
|
+
# Option example
|
39
|
+
# class_option :include-readme, default: true, type: :boolean
|
40
|
+
|
41
|
+
# Example of a generator step
|
42
|
+
# See: https://github.com/erikhuda/thor/wiki/Generators
|
43
|
+
# for further documentation on using thor generators.
|
44
|
+
#
|
45
|
+
# def create_<%= name.underscore %>
|
46
|
+
# target = File.join(
|
47
|
+
# parent_options[:root],
|
48
|
+
# "#{name.underscore}.rb",
|
49
|
+
# )
|
50
|
+
# template('templates/<%= name.underscore %>.tt', target)
|
51
|
+
# end
|
52
|
+
end
|
53
|
+
end
|