kdeploy 1.3.3 β 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +42 -1117
- data/README_EN.md +42 -1156
- data/lib/kdeploy/cli/cli.rb +28 -12
- data/lib/kdeploy/config/configuration.rb +24 -0
- data/lib/kdeploy/output/output_formatter.rb +3 -7
- data/lib/kdeploy/runner/runner.rb +2 -14
- data/lib/kdeploy/version.rb +1 -1
- metadata +2 -3
- data/AGENTS.md +0 -18
data/README_EN.md
CHANGED
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
|_| |___/
|
|
10
10
|
|
|
11
11
|
β‘ Lightweight Agentless Deployment Tool
|
|
12
|
-
π Deploy with confidence, scale with ease
|
|
13
12
|
```
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
Define hosts and tasks in Ruby DSL; execute deployments and configuration across servers via SSH/SCP with no agent on targets.
|
|
16
15
|
|
|
17
16
|
[](https://rubygems.org/gems/kdeploy)
|
|
18
17
|
[](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml)
|
|
@@ -20,1216 +19,103 @@ A lightweight, agentless deployment automation tool written in Ruby. Kdeploy ena
|
|
|
20
19
|
|
|
21
20
|
**Language**: [English](README_EN.md) | [δΈζ](README.md)
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
**Full requirements, DSL, API, architecture**: [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
- [Installation](#-installation)
|
|
27
|
-
- [Quick Start](#-quick-start)
|
|
28
|
-
- [Usage Guide](#-usage-guide)
|
|
29
|
-
- [Configuration](#-configuration)
|
|
30
|
-
- [Advanced Usage](#-advanced-usage)
|
|
31
|
-
- [Error Handling](#-error-handling)
|
|
32
|
-
- [Best Practices](#-best-practices)
|
|
33
|
-
- [Troubleshooting](#-troubleshooting)
|
|
34
|
-
- [Architecture](#-architecture)
|
|
35
|
-
- [Development](#-development)
|
|
36
|
-
- [Contributing](#-contributing)
|
|
37
|
-
- [License](#-license)
|
|
24
|
+
## Features
|
|
38
25
|
|
|
39
|
-
|
|
26
|
+
- Agentless SSH execution with multi-host concurrency
|
|
27
|
+
- Ruby DSL: hosts, roles, tasks; Chef-style resources (`package`, `service`, `template`, `sync`, etc.)
|
|
28
|
+
- File upload, ERB templates, directory sync (optional rsync fast path)
|
|
29
|
+
- Dry-run, JSON output, retry/timeout policies
|
|
40
30
|
|
|
41
|
-
|
|
31
|
+
**Stack**: Ruby, Thor, net-ssh, concurrent-ruby
|
|
42
32
|
|
|
43
|
-
|
|
44
|
-
- π **Elegant Ruby DSL**: Simple and expressive task definition syntax
|
|
45
|
-
- π **Concurrent Execution**: Efficient parallel task processing across multiple hosts
|
|
46
|
-
- π€ **File Upload Support**: Easy file and template deployment via SCP
|
|
47
|
-
- π **Task Status Tracking**: Real-time execution monitoring with detailed output
|
|
48
|
-
- π **ERB Template Support**: Dynamic configuration generation with variable substitution
|
|
49
|
-
- π― **Role-based Deployment**: Target specific server roles for organized deployments
|
|
50
|
-
- π **Dry Run Mode**: Preview tasks before execution without making changes
|
|
51
|
-
- π¨ **Color-coded Output**: Intuitive color scheme (Green: success, Red: errors, Yellow: warnings)
|
|
52
|
-
- βοΈ **Flexible Host Targeting**: Execute tasks on specific hosts, roles, or all hosts
|
|
53
|
-
- π **Multiple Authentication Methods**: Support for SSH keys and password authentication
|
|
54
|
-
- π **Execution Time Tracking**: Monitor task execution duration for performance analysis
|
|
33
|
+
## Installation
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
- **Thread-safe Execution**: Built on `concurrent-ruby` for reliable parallel processing
|
|
59
|
-
- **Custom Error Handling**: Detailed error types for better debugging
|
|
60
|
-
- **Configuration Management**: Centralized configuration with sensible defaults
|
|
61
|
-
- **Extensible Architecture**: Modular design for easy extension
|
|
62
|
-
- **Shell Completion**: Auto-completion support for Bash and Zsh
|
|
63
|
-
|
|
64
|
-
## π¦ Installation
|
|
65
|
-
|
|
66
|
-
### Requirements
|
|
67
|
-
|
|
68
|
-
- Ruby >= 2.7.0
|
|
69
|
-
- SSH access to target servers
|
|
70
|
-
- SSH keys or password authentication configured
|
|
71
|
-
|
|
72
|
-
### Install via RubyGems
|
|
35
|
+
Requires Ruby >= 2.7 and SSH access to targets.
|
|
73
36
|
|
|
74
37
|
```bash
|
|
75
38
|
gem install kdeploy
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Install via Bundler
|
|
79
|
-
|
|
80
|
-
Add this line to your application's `Gemfile`:
|
|
81
|
-
|
|
82
|
-
```ruby
|
|
83
|
-
gem 'kdeploy'
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
And then execute:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
bundle install
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Verify Installation
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
39
|
kdeploy version
|
|
96
40
|
```
|
|
97
41
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
**If `kdeploy` is not found**: the gem executable directory may not be in your PATH. Add to `~/.zshrc` or `~/.bashrc` then run `source ~/.zshrc`:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
export PATH="$(ruby -e 'puts Gem.bindir'):$PATH"
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Shell Completion
|
|
42
|
+
With Bundler: add `gem 'kdeploy'` and run `bundle install`.
|
|
107
43
|
|
|
108
|
-
|
|
44
|
+
If `kdeploy` is not found, add `$(ruby -e 'puts Gem.bindir')` to your `PATH`.
|
|
109
45
|
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
source "$(gem contents kdeploy | grep kdeploy.bash)"
|
|
113
|
-
```
|
|
46
|
+
## Quick Start
|
|
114
47
|
|
|
115
|
-
**For Zsh** (`~/.zshrc`):
|
|
116
48
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
49
|
+
kdeploy init my-deploy
|
|
50
|
+
cd my-deploy
|
|
119
51
|
```
|
|
120
52
|
|
|
121
|
-
|
|
122
|
-
1. For Bash: `source ~/.bashrc`
|
|
123
|
-
2. For Zsh: `source ~/.zshrc`
|
|
124
|
-
|
|
125
|
-
Now you can use Tab completion for:
|
|
126
|
-
- Commands: `kdeploy [TAB]`
|
|
127
|
-
- File paths: `kdeploy execute [TAB]`
|
|
128
|
-
- Options: `kdeploy execute deploy.rb [TAB]`
|
|
129
|
-
|
|
130
|
-
## π Quick Start
|
|
131
|
-
|
|
132
|
-
### 1. Initialize a New Project
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
kdeploy init my-deployment
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
This creates a new directory with:
|
|
139
|
-
- `deploy.rb` - Main deployment configuration file
|
|
140
|
-
- `config/` - Directory for configuration files and templates
|
|
141
|
-
- `README.md` - Project documentation
|
|
142
|
-
|
|
143
|
-
### 2. Configure Hosts and Tasks
|
|
144
|
-
|
|
145
|
-
Edit `deploy.rb` (using Chef-style resource DSL):
|
|
53
|
+
Edit `deploy.rb`:
|
|
146
54
|
|
|
147
55
|
```ruby
|
|
148
|
-
# Define hosts
|
|
149
56
|
host "web01", user: "ubuntu", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
|
|
150
|
-
|
|
151
|
-
role :web, %w[web01 web02]
|
|
152
|
-
|
|
153
|
-
# Define deployment task
|
|
154
|
-
task :deploy_web, roles: :web do
|
|
155
|
-
package "nginx"
|
|
156
|
-
directory "/etc/nginx/conf.d"
|
|
157
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
|
|
158
|
-
variables: { domain_name: "example.com", port: 3000 }
|
|
159
|
-
file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
|
|
160
|
-
run "nginx -t", sudo: true
|
|
161
|
-
service "nginx", action: %i[enable restart]
|
|
162
|
-
end
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### 3. Run Deployment
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
kdeploy execute deploy.rb deploy_web
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
## π Usage Guide
|
|
172
|
-
|
|
173
|
-
### Command Reference
|
|
174
|
-
|
|
175
|
-
#### `kdeploy init [DIR]`
|
|
176
|
-
|
|
177
|
-
Initialize a new deployment project.
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
# Initialize in current directory
|
|
181
|
-
kdeploy init .
|
|
182
|
-
|
|
183
|
-
# Initialize in named directory
|
|
184
|
-
kdeploy init my-deployment
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
#### `kdeploy execute TASK_FILE [TASK]`
|
|
188
|
-
|
|
189
|
-
Execute deployment tasks from a configuration file.
|
|
190
|
-
|
|
191
|
-
**Basic Usage:**
|
|
192
|
-
```bash
|
|
193
|
-
# Execute all tasks in the file
|
|
194
|
-
kdeploy execute deploy.rb
|
|
195
|
-
|
|
196
|
-
# Execute a specific task
|
|
197
|
-
kdeploy execute deploy.rb deploy_web
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Options:**
|
|
201
|
-
- `--limit HOSTS`: Limit execution to specific hosts (comma-separated)
|
|
202
|
-
- `--parallel NUM`: Number of parallel executions (default: 10)
|
|
203
|
-
- `--dry-run`: Preview mode - show what would be done without executing
|
|
204
|
-
- `--debug`: Debug mode - show detailed stdout/stderr output for `run` steps
|
|
205
|
-
- `--no-banner`: Do not print banner (automation-friendly)
|
|
206
|
-
- `--format FORMAT`: Output format (`text`|`json`, default `text`)
|
|
207
|
-
- `--retries N`: Retry count for network operations (default `0`)
|
|
208
|
-
- `--retry-delay SECONDS`: Delay between retries in seconds (default `1`)
|
|
209
|
-
- `--retry-on-nonzero`: Retry commands on nonzero exit status (default `false`)
|
|
210
|
-
- `--timeout SECONDS`: Per-host execution timeout in seconds (default: none)
|
|
211
|
-
- `--step-timeout SECONDS`: Per-step execution timeout in seconds (default: none)
|
|
212
|
-
- `--retry-policy JSON`: Retry policy JSON (overrides `.kdeploy.yml`)
|
|
213
|
-
- `--retry-policy-file PATH`: Retry policy JSON file (overrides `.kdeploy.yml`)
|
|
214
|
-
|
|
215
|
-
**Examples:**
|
|
216
|
-
```bash
|
|
217
|
-
# Preview deployment without executing
|
|
218
|
-
kdeploy execute deploy.rb deploy_web --dry-run
|
|
219
|
-
|
|
220
|
-
# Execute on specific hosts only
|
|
221
|
-
kdeploy execute deploy.rb deploy_web --limit web01,web02
|
|
222
|
-
|
|
223
|
-
# Use custom parallel count
|
|
224
|
-
kdeploy execute deploy.rb deploy_web --parallel 5
|
|
225
|
-
|
|
226
|
-
# Show detailed stdout/stderr output
|
|
227
|
-
kdeploy execute deploy.rb deploy_web --debug
|
|
228
|
-
|
|
229
|
-
# Machine-readable JSON output
|
|
230
|
-
kdeploy execute deploy.rb deploy_web --format json --no-banner
|
|
231
|
-
|
|
232
|
-
# Retry transient network failures
|
|
233
|
-
kdeploy execute deploy.rb deploy_web --retries 3 --retry-delay 1
|
|
234
|
-
|
|
235
|
-
# Retry on nonzero exit status
|
|
236
|
-
kdeploy execute deploy.rb deploy_web --retries 2 --retry-on-nonzero
|
|
237
|
-
|
|
238
|
-
# Set per-host timeout (seconds)
|
|
239
|
-
kdeploy execute deploy.rb deploy_web --timeout 120
|
|
240
|
-
|
|
241
|
-
# Set per-step timeout (seconds)
|
|
242
|
-
kdeploy execute deploy.rb deploy_web --step-timeout 30
|
|
243
|
-
|
|
244
|
-
# Override retry policy via CLI JSON
|
|
245
|
-
kdeploy execute deploy.rb deploy_web --retry-policy '{"run":{"retries":2,"retry_on_exit_codes":[2]}}'
|
|
246
|
-
|
|
247
|
-
# Override retry policy via file
|
|
248
|
-
kdeploy execute deploy.rb deploy_web --retry-policy-file ./retry_policy.example.json
|
|
249
|
-
|
|
250
|
-
# Combine options
|
|
251
|
-
kdeploy execute deploy.rb deploy_web --limit web01 --parallel 3 --dry-run
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
#### `kdeploy version`
|
|
255
|
-
|
|
256
|
-
Show version information.
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
kdeploy version
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
#### `kdeploy help [COMMAND]`
|
|
263
|
-
|
|
264
|
-
Show help information.
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
# Show general help
|
|
268
|
-
kdeploy help
|
|
269
|
-
|
|
270
|
-
# Show help for specific command
|
|
271
|
-
kdeploy help execute
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Host Definition
|
|
275
|
-
|
|
276
|
-
#### Basic Host Configuration
|
|
277
|
-
|
|
278
|
-
```ruby
|
|
279
|
-
# Single host with SSH key
|
|
280
|
-
host "web01",
|
|
281
|
-
user: "ubuntu",
|
|
282
|
-
ip: "10.0.0.1",
|
|
283
|
-
key: "~/.ssh/id_rsa"
|
|
284
|
-
|
|
285
|
-
# Host with password authentication
|
|
286
|
-
host "web02",
|
|
287
|
-
user: "admin",
|
|
288
|
-
ip: "10.0.0.2",
|
|
289
|
-
password: "your-password"
|
|
290
|
-
|
|
291
|
-
# Host with custom SSH port
|
|
292
|
-
host "web03",
|
|
293
|
-
user: "ubuntu",
|
|
294
|
-
ip: "10.0.0.3",
|
|
295
|
-
key: "~/.ssh/id_rsa",
|
|
296
|
-
port: 2222
|
|
297
|
-
|
|
298
|
-
# Host with sudo (all commands automatically use sudo)
|
|
299
|
-
host "web04",
|
|
300
|
-
user: "ubuntu",
|
|
301
|
-
ip: "10.0.0.4",
|
|
302
|
-
key: "~/.ssh/id_rsa",
|
|
303
|
-
use_sudo: true
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
#### Host Configuration Options
|
|
307
|
-
|
|
308
|
-
| Option | Type | Required | Description |
|
|
309
|
-
|--------|------|----------|-------------|
|
|
310
|
-
| `user` | String | Yes | SSH username |
|
|
311
|
-
| `ip` | String | Yes | Server IP address or hostname |
|
|
312
|
-
| `key` | String | No* | Path to SSH private key file |
|
|
313
|
-
| `password` | String | No* | SSH password |
|
|
314
|
-
| `port` | Integer | No | SSH port (default: 22) |
|
|
315
|
-
| `use_sudo` | Boolean | No | Automatically use sudo for all commands (default: false) |
|
|
316
|
-
| `sudo_password` | String | No | sudo password (if password authentication is required) |
|
|
317
|
-
|
|
318
|
-
\* Either `key` or `password` is required for authentication.
|
|
319
|
-
|
|
320
|
-
#### Dynamic Host Definition
|
|
321
|
-
|
|
322
|
-
```ruby
|
|
323
|
-
# Define multiple hosts programmatically
|
|
324
|
-
%w[web01 web02 web03].each do |name|
|
|
325
|
-
host name,
|
|
326
|
-
user: "ubuntu",
|
|
327
|
-
ip: "10.0.0.#{name[-1]}",
|
|
328
|
-
key: "~/.ssh/id_rsa"
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
# Define hosts from external source
|
|
332
|
-
require 'yaml'
|
|
333
|
-
hosts_config = YAML.load_file('hosts.yml')
|
|
334
|
-
hosts_config.each do |name, config|
|
|
335
|
-
host name, **config
|
|
336
|
-
end
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Role Management
|
|
340
|
-
|
|
341
|
-
Roles allow you to group hosts and target them collectively in tasks.
|
|
342
|
-
|
|
343
|
-
```ruby
|
|
344
|
-
# Define roles
|
|
345
|
-
role :web, %w[web01 web02 web03]
|
|
346
|
-
role :db, %w[db01 db02]
|
|
347
|
-
role :cache, %w[cache01]
|
|
348
|
-
role :all, %w[web01 web02 web03 db01 db02 cache01]
|
|
349
|
-
|
|
350
|
-
# Use roles in tasks
|
|
351
|
-
task :deploy_web, roles: :web do
|
|
352
|
-
# Executes on all web servers
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
task :backup_db, roles: :db do
|
|
356
|
-
# Executes on all database servers
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
# Multiple roles
|
|
360
|
-
task :deploy_all, roles: [:web, :cache] do
|
|
361
|
-
# Executes on web and cache servers
|
|
362
|
-
end
|
|
363
|
-
```
|
|
364
|
-
|
|
365
|
-
### Task Definition
|
|
366
|
-
|
|
367
|
-
#### Basic Task
|
|
368
|
-
|
|
369
|
-
```ruby
|
|
370
|
-
task :hello do
|
|
371
|
-
run "echo 'Hello, World!'"
|
|
372
|
-
end
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
#### Role-based Task
|
|
57
|
+
role :web, %w[web01]
|
|
376
58
|
|
|
377
|
-
```ruby
|
|
378
59
|
task :deploy_web, roles: :web do
|
|
379
|
-
service "nginx", action: :restart
|
|
380
|
-
end
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
#### Host-specific Task
|
|
384
|
-
|
|
385
|
-
```ruby
|
|
386
|
-
task :maintenance, on: %w[web01] do
|
|
387
|
-
service "nginx", action: :stop
|
|
388
|
-
run "apt-get update && apt-get upgrade -y", sudo: true
|
|
389
|
-
service "nginx", action: %i[start enable]
|
|
390
|
-
end
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
#### Task with Multiple Commands
|
|
394
|
-
|
|
395
|
-
```ruby
|
|
396
|
-
task :deploy_web, roles: :web do
|
|
397
|
-
package "nginx"
|
|
398
|
-
directory "/etc/nginx/conf.d"
|
|
399
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
|
|
400
|
-
file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
|
|
401
|
-
run "nginx -t", sudo: true
|
|
402
|
-
service "nginx", action: %i[enable restart]
|
|
403
|
-
end
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### Task Options
|
|
407
|
-
|
|
408
|
-
| Option | Type | Description |
|
|
409
|
-
|-------|------|-------------|
|
|
410
|
-
| `roles` | Symbol/Array | Execute on hosts with specified role(s) |
|
|
411
|
-
| `on` | Array | Execute on specific host(s) |
|
|
412
|
-
|
|
413
|
-
**Note**: If neither `roles` nor `on` is specified, the task executes on all defined hosts.
|
|
414
|
-
|
|
415
|
-
### Command Types
|
|
416
|
-
|
|
417
|
-
#### `run` - Execute Shell Commands
|
|
418
|
-
|
|
419
|
-
Execute commands on remote servers.
|
|
420
|
-
|
|
421
|
-
```ruby
|
|
422
|
-
# Single line command
|
|
423
|
-
run "sudo systemctl restart nginx"
|
|
424
|
-
|
|
425
|
-
# Multi-line command (recommended for complex commands)
|
|
426
|
-
run <<~SHELL
|
|
427
|
-
cd /var/www/app
|
|
428
|
-
git pull origin main
|
|
429
|
-
bundle install
|
|
430
|
-
sudo systemctl restart puma
|
|
431
|
-
SHELL
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
**Parameters:**
|
|
435
|
-
- `command`: Command string to execute
|
|
436
|
-
- `sudo`: Boolean, whether to execute this command with sudo (optional, default: nil, inherits host configuration)
|
|
437
|
-
|
|
438
|
-
**Using sudo:**
|
|
439
|
-
|
|
440
|
-
1. **At host level** (all commands automatically use sudo):
|
|
441
|
-
```ruby
|
|
442
|
-
host "web01",
|
|
443
|
-
user: "ubuntu",
|
|
444
|
-
ip: "10.0.0.1",
|
|
445
|
-
key: "~/.ssh/id_rsa",
|
|
446
|
-
use_sudo: true # All commands automatically use sudo
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
2. **At command level** (only specific commands use sudo):
|
|
450
|
-
```ruby
|
|
451
|
-
task :deploy do
|
|
452
|
-
run "systemctl restart nginx", sudo: true # Only this command uses sudo
|
|
453
|
-
run "echo 'Deployed'" # This command does not use sudo
|
|
454
|
-
end
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
3. **With sudo password** (if password authentication is required):
|
|
458
|
-
```ruby
|
|
459
|
-
host "web01",
|
|
460
|
-
user: "ubuntu",
|
|
461
|
-
ip: "10.0.0.1",
|
|
462
|
-
key: "~/.ssh/id_rsa",
|
|
463
|
-
use_sudo: true,
|
|
464
|
-
sudo_password: "your-sudo-password" # Only configure if password is required
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
**Notes:**
|
|
468
|
-
- If the command already starts with `sudo`, the tool will not add it again
|
|
469
|
-
- It's recommended to use NOPASSWD sudo configuration to avoid storing passwords in configuration files
|
|
470
|
-
- Command-level `sudo` option overrides host-level `use_sudo` configuration
|
|
471
|
-
|
|
472
|
-
**Best Practice**: Use heredoc (`<<~SHELL`) for multi-line commands to improve readability.
|
|
473
|
-
|
|
474
|
-
#### `upload` - Upload Files
|
|
475
|
-
|
|
476
|
-
Upload files to remote servers.
|
|
477
|
-
|
|
478
|
-
```ruby
|
|
479
|
-
upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
|
|
480
|
-
upload "./scripts/deploy.sh", "/tmp/deploy.sh"
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
**Parameters:**
|
|
484
|
-
- `source`: Local file path
|
|
485
|
-
- `destination`: Remote file path
|
|
486
|
-
|
|
487
|
-
#### `upload_template` - Upload ERB Templates
|
|
488
|
-
|
|
489
|
-
Upload and render ERB templates with variable substitution.
|
|
490
|
-
|
|
491
|
-
```ruby
|
|
492
|
-
upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
|
|
493
|
-
domain_name: "example.com",
|
|
494
|
-
port: 3000,
|
|
495
|
-
worker_processes: 4
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
**Parameters:**
|
|
499
|
-
- `source`: Local ERB template file path
|
|
500
|
-
- `destination`: Remote file path
|
|
501
|
-
- `variables`: Hash of variables for template rendering
|
|
502
|
-
|
|
503
|
-
#### `sync` - Directory Sync
|
|
504
|
-
|
|
505
|
-
Recursively sync a local directory to a remote server with filtering options.
|
|
506
|
-
|
|
507
|
-
```ruby
|
|
508
|
-
# Basic sync
|
|
509
|
-
sync "./app", "/var/www/app"
|
|
510
|
-
|
|
511
|
-
# Ignore specific files/dirs
|
|
512
|
-
sync "./app", "/var/www/app",
|
|
513
|
-
ignore: [".git", "*.log", "node_modules", "*.tmp"]
|
|
514
|
-
|
|
515
|
-
# Delete remote files not present locally
|
|
516
|
-
sync "./app", "/var/www/app",
|
|
517
|
-
ignore: [".git", "*.log"],
|
|
518
|
-
delete: true
|
|
519
|
-
|
|
520
|
-
# Exclude files (alias of ignore)
|
|
521
|
-
sync "./config", "/etc/app",
|
|
522
|
-
exclude: ["*.example", "*.bak", ".env.local"]
|
|
523
|
-
|
|
524
|
-
# Fast sync (prefer rsync when available)
|
|
525
|
-
sync "./app", "/var/www/app",
|
|
526
|
-
fast: true
|
|
527
|
-
|
|
528
|
-
# Parallel sync uploads
|
|
529
|
-
sync "./app", "/var/www/app",
|
|
530
|
-
parallel: 4
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
**Parameters:**
|
|
534
|
-
- `source`: Local source directory path
|
|
535
|
-
- `destination`: Remote destination directory path
|
|
536
|
-
- `ignore`: Patterns to ignore (gitignore-style)
|
|
537
|
-
- `exclude`: Same as `ignore` for clarity
|
|
538
|
-
- `delete`: Delete remote files not present locally (default: false)
|
|
539
|
-
- `fast`: Enable fast sync path (prefer rsync when available, default: false)
|
|
540
|
-
- `parallel`: Upload concurrency for sync (default: 1)
|
|
541
|
-
|
|
542
|
-
### Chef-Style Resource DSL
|
|
543
|
-
|
|
544
|
-
Kdeploy provides a declarative resource DSL similar to Chef, which can replace or mix with low-level primitives (`run`, `upload`, `upload_template`).
|
|
545
|
-
|
|
546
|
-
#### `package` - Install System Packages
|
|
547
|
-
|
|
548
|
-
```ruby
|
|
549
|
-
package "nginx"
|
|
550
|
-
package "nginx", version: "1.18"
|
|
551
|
-
package "nginx", platform: :yum # CentOS/RHEL
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
Uses apt (Ubuntu/Debian) by default; `platform: :yum` generates yum commands.
|
|
555
|
-
|
|
556
|
-
#### `service` - Manage System Services (systemd)
|
|
557
|
-
|
|
558
|
-
```ruby
|
|
559
|
-
service "nginx", action: [:enable, :start]
|
|
560
|
-
service "nginx", action: :restart
|
|
561
|
-
service "nginx", action: [:stop, :disable]
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
Supports `:start`, `:stop`, `:restart`, `:reload`, `:enable`, `:disable`.
|
|
565
|
-
|
|
566
|
-
#### `template` - Deploy ERB Templates
|
|
567
|
-
|
|
568
|
-
```ruby
|
|
569
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
|
|
570
|
-
# Or block syntax
|
|
571
|
-
template "/etc/app.conf" do
|
|
572
|
-
source "./config/app.erb"
|
|
573
|
-
variables(domain: "example.com")
|
|
574
|
-
end
|
|
575
|
-
```
|
|
576
|
-
|
|
577
|
-
#### `file` - Upload Local Files
|
|
578
|
-
|
|
579
|
-
```ruby
|
|
580
|
-
file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
#### `directory` - Ensure Remote Directory Exists
|
|
584
|
-
|
|
585
|
-
```ruby
|
|
586
|
-
directory "/etc/nginx/conf.d"
|
|
587
|
-
directory "/var/log/app", mode: "0755"
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
**Example: Deploy Nginx Using Resource DSL**
|
|
591
|
-
|
|
592
|
-
```ruby
|
|
593
|
-
task :deploy_nginx, roles: :web do
|
|
594
60
|
package "nginx"
|
|
595
|
-
directory "/etc/nginx/conf.d"
|
|
596
61
|
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
|
|
597
|
-
file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
|
|
598
62
|
run "nginx -t", sudo: true
|
|
599
63
|
service "nginx", action: %i[enable restart]
|
|
600
64
|
end
|
|
601
65
|
```
|
|
602
66
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
Kdeploy supports ERB (Embedded Ruby) templates for dynamic configuration generation.
|
|
606
|
-
|
|
607
|
-
#### Creating Templates
|
|
608
|
-
|
|
609
|
-
Create an ERB template file (e.g., `config/nginx.conf.erb`):
|
|
610
|
-
|
|
611
|
-
```erb
|
|
612
|
-
user nginx;
|
|
613
|
-
worker_processes <%= worker_processes %>;
|
|
614
|
-
error_log /var/log/nginx/error.log;
|
|
615
|
-
pid /run/nginx.pid;
|
|
616
|
-
|
|
617
|
-
events {
|
|
618
|
-
worker_connections <%= worker_connections %>;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
http {
|
|
622
|
-
include /etc/nginx/mime.types;
|
|
623
|
-
default_type application/octet-stream;
|
|
624
|
-
|
|
625
|
-
upstream app_servers {
|
|
626
|
-
server 127.0.0.1:<%= port %>;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
server {
|
|
630
|
-
listen 80;
|
|
631
|
-
server_name <%= domain_name %>;
|
|
632
|
-
|
|
633
|
-
location / {
|
|
634
|
-
proxy_pass http://app_servers;
|
|
635
|
-
proxy_http_version 1.1;
|
|
636
|
-
proxy_set_header Upgrade $http_upgrade;
|
|
637
|
-
proxy_set_header Connection 'upgrade';
|
|
638
|
-
proxy_set_header Host $host;
|
|
639
|
-
proxy_cache_bypass $http_upgrade;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
#### Using Templates
|
|
646
|
-
|
|
647
|
-
```ruby
|
|
648
|
-
task :deploy_config do
|
|
649
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
|
|
650
|
-
variables: { domain_name: "example.com", port: 3000, worker_processes: 4, worker_connections: 2048 }
|
|
651
|
-
end
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
#### Template Features
|
|
655
|
-
|
|
656
|
-
- Full ERB syntax support
|
|
657
|
-
- Variable substitution
|
|
658
|
-
- Conditional logic
|
|
659
|
-
- Loops and iterations
|
|
660
|
-
- Ruby code execution
|
|
661
|
-
|
|
662
|
-
### Inventory Block
|
|
663
|
-
|
|
664
|
-
Use the `inventory` block to organize host definitions:
|
|
665
|
-
|
|
666
|
-
```ruby
|
|
667
|
-
inventory do
|
|
668
|
-
host 'web01', user: 'ubuntu', ip: '10.0.0.1', key: '~/.ssh/id_rsa'
|
|
669
|
-
host 'web02', user: 'ubuntu', ip: '10.0.0.2', key: '~/.ssh/id_rsa'
|
|
670
|
-
host 'db01', user: 'root', ip: '10.0.0.3', key: '~/.ssh/id_rsa'
|
|
671
|
-
end
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
## βοΈ Configuration
|
|
675
|
-
|
|
676
|
-
### Default Configuration
|
|
677
|
-
|
|
678
|
-
Kdeploy uses sensible defaults that can be customized:
|
|
679
|
-
|
|
680
|
-
- **Default Parallel Count**: 10 concurrent executions
|
|
681
|
-
- **SSH Timeout**: 30 seconds
|
|
682
|
-
- **Host Key Verification**: Disabled (for convenience, enable in production)
|
|
683
|
-
|
|
684
|
-
### Environment Variables
|
|
685
|
-
|
|
686
|
-
You can override defaults using environment variables:
|
|
67
|
+
Run:
|
|
687
68
|
|
|
688
69
|
```bash
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
```
|
|
692
|
-
|
|
693
|
-
### Configuration File
|
|
694
|
-
|
|
695
|
-
For project-specific configuration, create a `.kdeploy.yml`:
|
|
696
|
-
|
|
697
|
-
```yaml
|
|
698
|
-
parallel: 5
|
|
699
|
-
ssh_timeout: 60
|
|
700
|
-
verify_host_key: true
|
|
701
|
-
retries: 2
|
|
702
|
-
retry_delay: 1
|
|
703
|
-
retry_on_nonzero: false
|
|
704
|
-
step_timeout: 30
|
|
705
|
-
sync_fast: false
|
|
706
|
-
sync_parallel: 4
|
|
707
|
-
retry_policy:
|
|
708
|
-
run:
|
|
709
|
-
retries: 2
|
|
710
|
-
retry_on_exit_codes: [2, 255]
|
|
711
|
-
upload:
|
|
712
|
-
retries: 0
|
|
70
|
+
kdeploy execute deploy.rb deploy_web --dry-run # preview
|
|
71
|
+
kdeploy execute deploy.rb deploy_web # execute
|
|
713
72
|
```
|
|
714
73
|
|
|
715
|
-
|
|
74
|
+
Common flags: `--limit web01`, `--parallel 5`, `--format json`, `--retries 3`. See [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md#fr-cli-04-execute-ιι‘Ή) for all options.
|
|
716
75
|
|
|
717
|
-
|
|
76
|
+
**Docker multi-host lab**: `cd docker/lab && docker compose --profile test up --build runner` ([docker/lab/README.md](docker/lab/README.md))
|
|
718
77
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
Use Ruby conditionals in your deployment files:
|
|
722
|
-
|
|
723
|
-
```ruby
|
|
724
|
-
task :deploy do
|
|
725
|
-
service "nginx", action: :stop if ENV['ENVIRONMENT'] == 'production'
|
|
726
|
-
|
|
727
|
-
file "/etc/nginx/nginx.conf", source: "./config/nginx.conf"
|
|
728
|
-
|
|
729
|
-
service "nginx", action: :start if ENV['ENVIRONMENT'] == 'production'
|
|
730
|
-
end
|
|
731
|
-
```
|
|
78
|
+
## Configuration
|
|
732
79
|
|
|
733
|
-
|
|
80
|
+
Place `.kdeploy.yml` in your project (walks up from CWD):
|
|
734
81
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
Example files: `retry_policy.example.json` / `retry_policy.example.yml`
|
|
742
|
-
|
|
743
|
-
### Looping Over Hosts
|
|
744
|
-
|
|
745
|
-
```ruby
|
|
746
|
-
# Execute different commands based on host
|
|
747
|
-
task :custom_setup do
|
|
748
|
-
@hosts.each do |name, config|
|
|
749
|
-
if name.start_with?('web')
|
|
750
|
-
run "echo 'Web server: #{name}'"
|
|
751
|
-
elsif name.start_with?('db')
|
|
752
|
-
run "echo 'Database server: #{name}'"
|
|
753
|
-
end
|
|
754
|
-
end
|
|
755
|
-
end
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
### Error Handling in Tasks
|
|
759
|
-
|
|
760
|
-
```ruby
|
|
761
|
-
task :deploy do
|
|
762
|
-
service "nginx", action: :stop
|
|
763
|
-
file "/etc/nginx/nginx.conf", source: "./config/nginx.conf"
|
|
764
|
-
run "nginx -t", sudo: true # run raises on invalid config
|
|
765
|
-
service "nginx", action: :start
|
|
766
|
-
end
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
### Using External Libraries
|
|
770
|
-
|
|
771
|
-
```ruby
|
|
772
|
-
require 'yaml'
|
|
773
|
-
require 'json'
|
|
774
|
-
|
|
775
|
-
# Load configuration from external files
|
|
776
|
-
config = YAML.load_file('config.yml')
|
|
777
|
-
|
|
778
|
-
task :deploy do
|
|
779
|
-
config['commands'].each do |cmd|
|
|
780
|
-
run cmd
|
|
781
|
-
end
|
|
782
|
-
end
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
### Task Dependencies
|
|
786
|
-
|
|
787
|
-
While Kdeploy doesn't have built-in task dependencies, you can achieve this with Ruby:
|
|
788
|
-
|
|
789
|
-
```ruby
|
|
790
|
-
task :setup do
|
|
791
|
-
run "echo 'Setting up...'"
|
|
792
|
-
end
|
|
793
|
-
|
|
794
|
-
task :deploy do
|
|
795
|
-
# Manually call setup task
|
|
796
|
-
self.class.kdeploy_tasks[:setup][:block].call.each do |cmd|
|
|
797
|
-
case cmd[:type]
|
|
798
|
-
when :run
|
|
799
|
-
run cmd[:command]
|
|
800
|
-
when :upload
|
|
801
|
-
upload cmd[:source], cmd[:destination]
|
|
802
|
-
end
|
|
803
|
-
end
|
|
804
|
-
|
|
805
|
-
run "echo 'Deploying...'"
|
|
806
|
-
end
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
## π¨ Error Handling
|
|
810
|
-
|
|
811
|
-
### Error Types
|
|
812
|
-
|
|
813
|
-
Kdeploy provides specific error types for better debugging:
|
|
814
|
-
|
|
815
|
-
- `Kdeploy::TaskNotFoundError` - Task not found
|
|
816
|
-
- `Kdeploy::HostNotFoundError` - Host not found
|
|
817
|
-
- `Kdeploy::SSHError` - SSH operation failed
|
|
818
|
-
- `Kdeploy::SCPError` - SCP upload failed
|
|
819
|
-
- `Kdeploy::TemplateError` - Template rendering failed
|
|
820
|
-
- `Kdeploy::ConfigurationError` - Configuration error
|
|
821
|
-
- `Kdeploy::FileNotFoundError` - File not found
|
|
822
|
-
|
|
823
|
-
### Error Output
|
|
824
|
-
|
|
825
|
-
Errors are displayed with:
|
|
826
|
-
- Red color coding
|
|
827
|
-
- Detailed error messages
|
|
828
|
-
- Host information
|
|
829
|
-
- Original error context
|
|
830
|
-
|
|
831
|
-
### Handling Errors
|
|
832
|
-
|
|
833
|
-
```ruby
|
|
834
|
-
# In your deployment file
|
|
835
|
-
begin
|
|
836
|
-
task :deploy do
|
|
837
|
-
run "risky-command"
|
|
838
|
-
end
|
|
839
|
-
rescue Kdeploy::SSHError => e
|
|
840
|
-
puts "SSH Error: #{e.message}"
|
|
841
|
-
# Handle error
|
|
842
|
-
end
|
|
843
|
-
```
|
|
844
|
-
|
|
845
|
-
## π‘ Best Practices
|
|
846
|
-
|
|
847
|
-
### 1. Use Heredoc for Multi-line Commands
|
|
848
|
-
|
|
849
|
-
```ruby
|
|
850
|
-
# β
Good
|
|
851
|
-
run <<~SHELL
|
|
852
|
-
cd /var/www/app
|
|
853
|
-
git pull origin main
|
|
854
|
-
bundle install
|
|
855
|
-
SHELL
|
|
856
|
-
|
|
857
|
-
# β Avoid
|
|
858
|
-
run "cd /var/www/app && git pull origin main && bundle install"
|
|
859
|
-
```
|
|
860
|
-
|
|
861
|
-
### 2. Organize with Roles
|
|
862
|
-
|
|
863
|
-
```ruby
|
|
864
|
-
# β
Good - Use roles for organization
|
|
865
|
-
role :web, %w[web01 web02]
|
|
866
|
-
role :db, %w[db01 db02]
|
|
867
|
-
|
|
868
|
-
task :deploy_web, roles: :web do
|
|
869
|
-
# ...
|
|
870
|
-
end
|
|
871
|
-
|
|
872
|
-
# β Avoid - Hardcoding host names
|
|
873
|
-
task :deploy do
|
|
874
|
-
# Hard to maintain
|
|
875
|
-
end
|
|
876
|
-
```
|
|
877
|
-
|
|
878
|
-
### 3. Use Templates for Dynamic Configuration
|
|
879
|
-
|
|
880
|
-
```ruby
|
|
881
|
-
# β
Good - Use template resource
|
|
882
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb",
|
|
883
|
-
variables: { domain_name: "example.com", port: 3000 }
|
|
884
|
-
|
|
885
|
-
# β Avoid - Hardcoding values
|
|
886
|
-
run "echo 'server_name example.com;' > /etc/nginx/nginx.conf"
|
|
887
|
-
```
|
|
888
|
-
|
|
889
|
-
### 4. Validate Before Deployment
|
|
890
|
-
|
|
891
|
-
```ruby
|
|
892
|
-
task :deploy do
|
|
893
|
-
template "/etc/nginx/nginx.conf", source: "./config/nginx.conf.erb", variables: { port: 3000 }
|
|
894
|
-
file "/etc/nginx/conf.d/app.conf", source: "./config/app.conf"
|
|
895
|
-
run "nginx -t", sudo: true # run raises on invalid config
|
|
896
|
-
service "nginx", action: :reload
|
|
897
|
-
end
|
|
82
|
+
```yaml
|
|
83
|
+
parallel: 10
|
|
84
|
+
ssh_timeout: 30
|
|
85
|
+
verify_host_key: never
|
|
86
|
+
retries: 0
|
|
898
87
|
```
|
|
899
88
|
|
|
900
|
-
|
|
89
|
+
Retry policy examples: `retry_policy.example.json`
|
|
901
90
|
|
|
902
|
-
|
|
91
|
+
## Samples
|
|
903
92
|
|
|
904
93
|
```bash
|
|
94
|
+
cd samples
|
|
905
95
|
kdeploy execute deploy.rb deploy_web --dry-run
|
|
906
96
|
```
|
|
907
97
|
|
|
908
|
-
|
|
98
|
+
Includes Nginx, Node Exporter, directory sync; Vagrant available for local testing.
|
|
909
99
|
|
|
910
|
-
|
|
911
|
-
project/
|
|
912
|
-
βββ deploy.rb # Main deployment file
|
|
913
|
-
βββ config/ # Configuration files
|
|
914
|
-
β βββ nginx.conf.erb # Templates
|
|
915
|
-
β βββ app.conf # Static configs
|
|
916
|
-
βββ scripts/ # Helper scripts
|
|
917
|
-
βββ deploy.sh
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
### 7. Version Control
|
|
921
|
-
|
|
922
|
-
- Commit `deploy.rb` and templates
|
|
923
|
-
- Use `.gitignore` for sensitive files
|
|
924
|
-
- Store secrets in environment variables
|
|
925
|
-
|
|
926
|
-
### 8. Parallel Execution
|
|
927
|
-
|
|
928
|
-
Adjust parallel count based on your infrastructure:
|
|
100
|
+
## Development
|
|
929
101
|
|
|
930
102
|
```bash
|
|
931
|
-
|
|
932
|
-
kdeploy execute deploy.rb deploy --parallel 20
|
|
933
|
-
|
|
934
|
-
# For limited resources, decrease
|
|
935
|
-
kdeploy execute deploy.rb deploy --parallel 3
|
|
936
|
-
```
|
|
937
|
-
|
|
938
|
-
## π Troubleshooting
|
|
939
|
-
|
|
940
|
-
### Common Issues
|
|
941
|
-
|
|
942
|
-
#### SSH Authentication Failed
|
|
943
|
-
|
|
944
|
-
**Problem**: `SSH authentication failed`
|
|
945
|
-
|
|
946
|
-
**Solutions**:
|
|
947
|
-
1. Verify SSH key path is correct
|
|
948
|
-
2. Check key permissions: `chmod 600 ~/.ssh/id_rsa`
|
|
949
|
-
3. Test SSH connection manually: `ssh user@host`
|
|
950
|
-
4. Verify username and IP address
|
|
951
|
-
|
|
952
|
-
#### Host Not Found
|
|
953
|
-
|
|
954
|
-
**Problem**: `No hosts found for task`
|
|
955
|
-
|
|
956
|
-
**Solutions**:
|
|
957
|
-
1. Verify host names in task match defined hosts
|
|
958
|
-
2. Check role definitions
|
|
959
|
-
3. Verify `--limit` option if used
|
|
960
|
-
|
|
961
|
-
#### Command Execution Failed
|
|
962
|
-
|
|
963
|
-
**Problem**: Commands fail on remote server
|
|
964
|
-
|
|
965
|
-
**Solutions**:
|
|
966
|
-
1. Test commands manually on target server
|
|
967
|
-
2. Check user permissions (may need sudo)
|
|
968
|
-
3. Verify command syntax
|
|
969
|
-
4. Check server logs
|
|
970
|
-
|
|
971
|
-
#### Template Rendering Error
|
|
972
|
-
|
|
973
|
-
**Problem**: Template upload fails
|
|
974
|
-
|
|
975
|
-
**Solutions**:
|
|
976
|
-
1. Verify ERB syntax in template
|
|
977
|
-
2. Check all required variables are provided
|
|
978
|
-
3. Validate template file exists
|
|
979
|
-
4. Test template rendering locally
|
|
980
|
-
|
|
981
|
-
#### Connection Timeout
|
|
982
|
-
|
|
983
|
-
**Problem**: SSH connection times out
|
|
984
|
-
|
|
985
|
-
**Solutions**:
|
|
986
|
-
1. Check network connectivity
|
|
987
|
-
2. Verify firewall rules
|
|
988
|
-
3. Increase timeout in configuration
|
|
989
|
-
4. Check SSH service on target server
|
|
990
|
-
|
|
991
|
-
### Debug Mode
|
|
992
|
-
|
|
993
|
-
Enable verbose output by checking the execution output. Kdeploy provides detailed information about:
|
|
994
|
-
- Task execution status
|
|
995
|
-
- Command output
|
|
996
|
-
- Error messages
|
|
997
|
-
- Execution duration
|
|
998
|
-
|
|
999
|
-
### Getting Help
|
|
1000
|
-
|
|
1001
|
-
- Check [GitHub Issues](https://github.com/kevin197011/kdeploy/issues)
|
|
1002
|
-
- Review example projects
|
|
1003
|
-
- Read the documentation
|
|
1004
|
-
- Ask in discussions
|
|
1005
|
-
|
|
1006
|
-
## ποΈ Architecture
|
|
1007
|
-
|
|
1008
|
-
### Core Components
|
|
1009
|
-
|
|
1010
|
-
- **CLI** (`cli.rb`): Command-line interface using Thor
|
|
1011
|
-
- **DSL** (`dsl.rb`): Domain-specific language for task definition
|
|
1012
|
-
- **Executor** (`executor.rb`): SSH/SCP execution engine
|
|
1013
|
-
- **Runner** (`runner.rb`): Concurrent task execution coordinator
|
|
1014
|
-
- **CommandExecutor** (`command_executor.rb`): Individual command execution
|
|
1015
|
-
- **Template** (`template.rb`): ERB template rendering
|
|
1016
|
-
- **Output** (`output.rb`): Output formatting and display
|
|
1017
|
-
- **Configuration** (`configuration.rb`): Configuration management
|
|
1018
|
-
- **Errors** (`errors.rb`): Custom error types
|
|
1019
|
-
|
|
1020
|
-
### Execution Flow
|
|
1021
|
-
|
|
1022
|
-
1. **Parse Configuration**: Load and parse `deploy.rb`
|
|
1023
|
-
2. **Resolve Hosts**: Determine target hosts based on task definition
|
|
1024
|
-
3. **Execute Concurrently**: Run tasks in parallel across hosts, executing commands in order per host
|
|
1025
|
-
4. **Collect Results**: Gather execution results and status
|
|
1026
|
-
5. **Display Output**: Format and display results to user
|
|
1027
|
-
|
|
1028
|
-
### Concurrency Model
|
|
1029
|
-
|
|
1030
|
-
Kdeploy uses `concurrent-ruby` with a fixed thread pool:
|
|
1031
|
-
- Default: 10 concurrent executions
|
|
1032
|
-
- Configurable via `--parallel` option
|
|
1033
|
-
- Thread-safe result collection
|
|
1034
|
-
- Automatic resource cleanup
|
|
1035
|
-
|
|
1036
|
-
## π§ Development
|
|
1037
|
-
|
|
1038
|
-
### Setup Development Environment
|
|
1039
|
-
|
|
1040
|
-
```bash
|
|
1041
|
-
# Clone repository
|
|
1042
|
-
git clone https://github.com/kevin197011/kdeploy.git
|
|
1043
|
-
cd kdeploy
|
|
1044
|
-
|
|
1045
|
-
# Install dependencies
|
|
103
|
+
git clone git@github.com:kevin197011/kdeploy.git && cd kdeploy
|
|
1046
104
|
bundle install
|
|
1047
|
-
|
|
1048
|
-
# Run tests
|
|
1049
105
|
bundle exec rspec
|
|
1050
|
-
|
|
1051
|
-
# Run console
|
|
1052
|
-
bin/console
|
|
1053
|
-
```
|
|
1054
|
-
|
|
1055
|
-
### Project Structure
|
|
1056
|
-
|
|
1057
|
-
```
|
|
1058
|
-
kdeploy/
|
|
1059
|
-
βββ lib/
|
|
1060
|
-
β βββ kdeploy/
|
|
1061
|
-
β βββ cli.rb # CLI interface
|
|
1062
|
-
β βββ dsl.rb # DSL definition
|
|
1063
|
-
β βββ executor.rb # SSH/SCP executor
|
|
1064
|
-
β βββ runner.rb # Task runner
|
|
1065
|
-
β βββ command_executor.rb # Command executor
|
|
1066
|
-
β βββ template.rb # Template handler
|
|
1067
|
-
β βββ output.rb # Output interface
|
|
1068
|
-
β βββ configuration.rb # Configuration
|
|
1069
|
-
β βββ errors.rb # Error types
|
|
1070
|
-
β βββ ...
|
|
1071
|
-
βββ spec/ # Tests
|
|
1072
|
-
βββ exe/ # Executables
|
|
1073
|
-
βββ sample/ # Example projects
|
|
1074
|
-
βββ README.md # This file
|
|
1075
|
-
```
|
|
1076
|
-
|
|
1077
|
-
### Running Tests
|
|
1078
|
-
|
|
1079
|
-
```bash
|
|
1080
|
-
# Run all tests
|
|
1081
|
-
bundle exec rspec
|
|
1082
|
-
|
|
1083
|
-
# Run specific test file
|
|
1084
|
-
bundle exec rspec spec/kdeploy_spec.rb
|
|
1085
|
-
|
|
1086
|
-
# Run with coverage
|
|
1087
|
-
COVERAGE=true bundle exec rspec
|
|
1088
|
-
```
|
|
1089
|
-
|
|
1090
|
-
### Building the Gem
|
|
1091
|
-
|
|
1092
|
-
```bash
|
|
1093
|
-
# Build gem
|
|
1094
|
-
gem build kdeploy.gemspec
|
|
1095
|
-
|
|
1096
|
-
# Install locally
|
|
1097
|
-
gem install ./kdeploy-*.gem
|
|
1098
|
-
```
|
|
1099
|
-
|
|
1100
|
-
### Code Style
|
|
1101
|
-
|
|
1102
|
-
The project uses RuboCop for code style:
|
|
1103
|
-
|
|
1104
|
-
```bash
|
|
1105
|
-
# Check style
|
|
1106
106
|
bundle exec rubocop
|
|
1107
|
-
|
|
1108
|
-
# Auto-fix issues
|
|
1109
|
-
bundle exec rubocop -a
|
|
1110
|
-
```
|
|
1111
|
-
|
|
1112
|
-
## π€ Contributing
|
|
1113
|
-
|
|
1114
|
-
Contributions are welcome! Please follow these steps:
|
|
1115
|
-
|
|
1116
|
-
1. **Fork the repository**
|
|
1117
|
-
2. **Create a feature branch**: `git checkout -b feature/my-new-feature`
|
|
1118
|
-
3. **Make your changes**: Follow the code style and add tests
|
|
1119
|
-
4. **Commit your changes**: Use conventional commit messages
|
|
1120
|
-
5. **Push to the branch**: `git push origin feature/my-new-feature`
|
|
1121
|
-
6. **Create a Pull Request**: Provide a clear description of changes
|
|
1122
|
-
|
|
1123
|
-
### Contribution Guidelines
|
|
1124
|
-
|
|
1125
|
-
- Follow existing code style
|
|
1126
|
-
- Add tests for new features
|
|
1127
|
-
- Update documentation
|
|
1128
|
-
- Ensure all tests pass
|
|
1129
|
-
- Follow conventional commit format
|
|
1130
|
-
|
|
1131
|
-
### Commit Message Format
|
|
1132
|
-
|
|
1133
|
-
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
1134
|
-
|
|
1135
|
-
```
|
|
1136
|
-
<type>(<scope>): <subject>
|
|
1137
|
-
|
|
1138
|
-
<body>
|
|
1139
|
-
|
|
1140
|
-
<footer>
|
|
1141
|
-
```
|
|
1142
|
-
|
|
1143
|
-
Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
|
1144
|
-
|
|
1145
|
-
## π Examples
|
|
1146
|
-
|
|
1147
|
-
### Example Project
|
|
1148
|
-
|
|
1149
|
-
The [sample/](sample/) directory in this repo provides a complete example with Nginx, Node Exporter, directory sync tasks, and Vagrant support for local testing:
|
|
1150
|
-
|
|
1151
|
-
```bash
|
|
1152
|
-
cd sample
|
|
1153
|
-
vagrant up
|
|
1154
|
-
kdeploy execute deploy.rb deploy_web --dry-run # Preview
|
|
1155
|
-
kdeploy execute deploy.rb deploy_web # Execute
|
|
1156
|
-
```
|
|
1157
|
-
|
|
1158
|
-
### Common Deployment Scenarios
|
|
1159
|
-
|
|
1160
|
-
#### Web Application Deployment
|
|
1161
|
-
|
|
1162
|
-
```ruby
|
|
1163
|
-
host "web01", user: "deploy", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
|
|
1164
|
-
role :web, %w[web01]
|
|
1165
|
-
|
|
1166
|
-
task :deploy_app, roles: :web do
|
|
1167
|
-
run <<~SHELL
|
|
1168
|
-
cd /var/www/app
|
|
1169
|
-
git pull origin main
|
|
1170
|
-
bundle install
|
|
1171
|
-
rake db:migrate
|
|
1172
|
-
sudo systemctl restart puma
|
|
1173
|
-
SHELL
|
|
1174
|
-
end
|
|
1175
107
|
```
|
|
1176
108
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
```ruby
|
|
1180
|
-
host "db01", user: "postgres", ip: "10.0.0.10", key: "~/.ssh/id_rsa"
|
|
1181
|
-
role :db, %w[db01]
|
|
1182
|
-
|
|
1183
|
-
task :backup, roles: :db do
|
|
1184
|
-
run <<~SHELL
|
|
1185
|
-
pg_dump mydb > /tmp/backup_$(date +%Y%m%d).sql
|
|
1186
|
-
gzip /tmp/backup_*.sql
|
|
1187
|
-
aws s3 cp /tmp/backup_*.sql.gz s3://backups/
|
|
1188
|
-
rm /tmp/backup_*.sql.gz
|
|
1189
|
-
SHELL
|
|
1190
|
-
end
|
|
1191
|
-
```
|
|
1192
|
-
|
|
1193
|
-
#### Configuration Management
|
|
1194
|
-
|
|
1195
|
-
```ruby
|
|
1196
|
-
task :update_config, roles: :web do
|
|
1197
|
-
template "/etc/app/config.yml", source: "./config/app.yml.erb",
|
|
1198
|
-
variables: { environment: "production", database_url: ENV['DATABASE_URL'], redis_url: ENV['REDIS_URL'] }
|
|
1199
|
-
service "app", action: :reload
|
|
1200
|
-
end
|
|
1201
|
-
```
|
|
1202
|
-
|
|
1203
|
-
#### Directory Sync Deployment
|
|
1204
|
-
|
|
1205
|
-
```ruby
|
|
1206
|
-
task :deploy_app, roles: :web do
|
|
1207
|
-
sync "./app", "/var/www/app",
|
|
1208
|
-
ignore: [".git", "*.log", "node_modules", ".env.local", "*.tmp"],
|
|
1209
|
-
delete: true,
|
|
1210
|
-
fast: true # prefer rsync when available
|
|
1211
|
-
sync "./config", "/etc/app", exclude: ["*.example", "*.bak"]
|
|
1212
|
-
service "app", action: :restart
|
|
1213
|
-
end
|
|
1214
|
-
```
|
|
1215
|
-
|
|
1216
|
-
## π License
|
|
1217
|
-
|
|
1218
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
109
|
+
Requirements and acceptance criteria: [docs/REQUIREMENTS.md](docs/REQUIREMENTS.md)
|
|
1219
110
|
|
|
1220
|
-
##
|
|
111
|
+
## Contributing
|
|
1221
112
|
|
|
1222
|
-
|
|
1223
|
-
- **RubyGems**: https://rubygems.org/gems/kdeploy
|
|
1224
|
-
- **Issues**: https://github.com/kevin197011/kdeploy/issues
|
|
1225
|
-
- **Sample**: [sample/](sample/) directory (includes Vagrant config)
|
|
113
|
+
Fork β feature branch β tests pass β PR. Use [Conventional Commits](https://www.conventionalcommits.org/).
|
|
1226
114
|
|
|
1227
|
-
##
|
|
115
|
+
## License
|
|
1228
116
|
|
|
1229
|
-
|
|
1230
|
-
- Uses [net-ssh](https://github.com/net-ssh/net-ssh) for SSH operations
|
|
1231
|
-
- Powered by [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) for concurrency
|
|
117
|
+
[MIT](https://opensource.org/licenses/MIT)
|
|
1232
118
|
|
|
1233
|
-
|
|
119
|
+
## Links
|
|
1234
120
|
|
|
1235
|
-
|
|
121
|
+
- [GitHub](https://github.com/kevin197011/kdeploy) Β· [RubyGems](https://rubygems.org/gems/kdeploy) Β· [Issues](https://github.com/kevin197011/kdeploy/issues)
|