kdeploy 1.2.6 β†’ 1.2.7

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +371 -419
  3. data/README_EN.md +1031 -0
  4. data/lib/kdeploy/version.rb +1 -1
  5. metadata +2 -1
data/README_EN.md ADDED
@@ -0,0 +1,1031 @@
1
+ # Kdeploy
2
+
3
+ ```
4
+ _ _
5
+ /\ /\__| | ___ _ __ | | ___ _ _
6
+ / //_/ _` |/ _ \ '_ \| |/ _ \| | | |
7
+ / __ \ (_| | __/ |_) | | (_) | |_| |
8
+ \/ \/\__,_|\___| .__/|_|\___/ \__, |
9
+ |_| |___/
10
+
11
+ ⚑ Lightweight Agentless Deployment Tool
12
+ πŸš€ Deploy with confidence, scale with ease
13
+ ```
14
+
15
+ A lightweight, agentless deployment automation tool written in Ruby. Kdeploy enables you to deploy applications, manage configurations, and execute tasks across multiple servers using SSH, without requiring any agents or daemons on target machines.
16
+
17
+ [![Gem Version](https://img.shields.io/gem/v/kdeploy)](https://rubygems.org/gems/kdeploy)
18
+ [![Ruby](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml/badge.svg)](https://github.com/kevin197011/kdeploy/actions/workflows/gem-push.yml)
19
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
20
+
21
+ **Language**: [English](README_EN.md) | [δΈ­ζ–‡](README.md)
22
+
23
+ ## Table of Contents
24
+
25
+ - [Features](#-features)
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)
38
+
39
+ ## 🌟 Features
40
+
41
+ ### Core Features
42
+
43
+ - πŸ”‘ **Agentless Remote Deployment**: Uses SSH for secure remote execution, no agents required
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
55
+
56
+ ### Technical Features
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
73
+
74
+ ```bash
75
+ 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
+ kdeploy version
96
+ ```
97
+
98
+ You should see the version information and banner.
99
+
100
+ ### Shell Completion
101
+
102
+ Kdeploy automatically configures shell completion during installation. If needed, manually add to your shell config:
103
+
104
+ **For Bash** (`~/.bashrc`):
105
+ ```bash
106
+ source "$(gem contents kdeploy | grep kdeploy.bash)"
107
+ ```
108
+
109
+ **For Zsh** (`~/.zshrc`):
110
+ ```bash
111
+ source "$(gem contents kdeploy | grep kdeploy.zsh)"
112
+ autoload -Uz compinit && compinit
113
+ ```
114
+
115
+ After adding the configuration:
116
+ 1. For Bash: `source ~/.bashrc`
117
+ 2. For Zsh: `source ~/.zshrc`
118
+
119
+ Now you can use Tab completion for:
120
+ - Commands: `kdeploy [TAB]`
121
+ - File paths: `kdeploy execute [TAB]`
122
+ - Options: `kdeploy execute deploy.rb [TAB]`
123
+
124
+ ## πŸš€ Quick Start
125
+
126
+ ### 1. Initialize a New Project
127
+
128
+ ```bash
129
+ kdeploy init my-deployment
130
+ ```
131
+
132
+ This creates a new directory with:
133
+ - `deploy.rb` - Main deployment configuration file
134
+ - `config/` - Directory for configuration files and templates
135
+ - `README.md` - Project documentation
136
+
137
+ ### 2. Configure Hosts and Tasks
138
+
139
+ Edit `deploy.rb`:
140
+
141
+ ```ruby
142
+ # Define hosts
143
+ host "web01", user: "ubuntu", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
144
+ host "web02", user: "ubuntu", ip: "10.0.0.2", key: "~/.ssh/id_rsa"
145
+
146
+ # Define roles
147
+ role :web, %w[web01 web02]
148
+
149
+ # Define deployment task
150
+ task :deploy, roles: :web do
151
+ run <<~SHELL
152
+ sudo systemctl stop nginx
153
+ echo "Deploying application..."
154
+ SHELL
155
+
156
+ upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
157
+ domain_name: "example.com",
158
+ port: 3000
159
+
160
+ run "sudo systemctl start nginx"
161
+ end
162
+ ```
163
+
164
+ ### 3. Run Deployment
165
+
166
+ ```bash
167
+ kdeploy execute deploy.rb deploy
168
+ ```
169
+
170
+ ## πŸ“– Usage Guide
171
+
172
+ ### Command Reference
173
+
174
+ #### `kdeploy init [DIR]`
175
+
176
+ Initialize a new deployment project.
177
+
178
+ ```bash
179
+ # Initialize in current directory
180
+ kdeploy init .
181
+
182
+ # Initialize in named directory
183
+ kdeploy init my-deployment
184
+ ```
185
+
186
+ #### `kdeploy execute TASK_FILE [TASK]`
187
+
188
+ Execute deployment tasks from a configuration file.
189
+
190
+ **Basic Usage:**
191
+ ```bash
192
+ # Execute all tasks in the file
193
+ kdeploy execute deploy.rb
194
+
195
+ # Execute a specific task
196
+ kdeploy execute deploy.rb deploy_web
197
+ ```
198
+
199
+ **Options:**
200
+ - `--limit HOSTS`: Limit execution to specific hosts (comma-separated)
201
+ - `--parallel NUM`: Number of parallel executions (default: 10)
202
+ - `--dry-run`: Preview mode - show what would be done without executing
203
+
204
+ **Examples:**
205
+ ```bash
206
+ # Preview deployment without executing
207
+ kdeploy execute deploy.rb deploy_web --dry-run
208
+
209
+ # Execute on specific hosts only
210
+ kdeploy execute deploy.rb deploy_web --limit web01,web02
211
+
212
+ # Use custom parallel count
213
+ kdeploy execute deploy.rb deploy_web --parallel 5
214
+
215
+ # Combine options
216
+ kdeploy execute deploy.rb deploy_web --limit web01 --parallel 3 --dry-run
217
+ ```
218
+
219
+ #### `kdeploy version`
220
+
221
+ Show version information.
222
+
223
+ ```bash
224
+ kdeploy version
225
+ ```
226
+
227
+ #### `kdeploy help [COMMAND]`
228
+
229
+ Show help information.
230
+
231
+ ```bash
232
+ # Show general help
233
+ kdeploy help
234
+
235
+ # Show help for specific command
236
+ kdeploy help execute
237
+ ```
238
+
239
+ ### Host Definition
240
+
241
+ #### Basic Host Configuration
242
+
243
+ ```ruby
244
+ # Single host with SSH key
245
+ host "web01",
246
+ user: "ubuntu",
247
+ ip: "10.0.0.1",
248
+ key: "~/.ssh/id_rsa"
249
+
250
+ # Host with password authentication
251
+ host "web02",
252
+ user: "admin",
253
+ ip: "10.0.0.2",
254
+ password: "your-password"
255
+
256
+ # Host with custom SSH port
257
+ host "web03",
258
+ user: "ubuntu",
259
+ ip: "10.0.0.3",
260
+ key: "~/.ssh/id_rsa",
261
+ port: 2222
262
+ ```
263
+
264
+ #### Host Configuration Options
265
+
266
+ | Option | Type | Required | Description |
267
+ |--------|------|----------|-------------|
268
+ | `user` | String | Yes | SSH username |
269
+ | `ip` | String | Yes | Server IP address or hostname |
270
+ | `key` | String | No* | Path to SSH private key file |
271
+ | `password` | String | No* | SSH password |
272
+ | `port` | Integer | No | SSH port (default: 22) |
273
+
274
+ \* Either `key` or `password` is required for authentication.
275
+
276
+ #### Dynamic Host Definition
277
+
278
+ ```ruby
279
+ # Define multiple hosts programmatically
280
+ %w[web01 web02 web03].each do |name|
281
+ host name,
282
+ user: "ubuntu",
283
+ ip: "10.0.0.#{name[-1]}",
284
+ key: "~/.ssh/id_rsa"
285
+ end
286
+
287
+ # Define hosts from external source
288
+ require 'yaml'
289
+ hosts_config = YAML.load_file('hosts.yml')
290
+ hosts_config.each do |name, config|
291
+ host name, **config
292
+ end
293
+ ```
294
+
295
+ ### Role Management
296
+
297
+ Roles allow you to group hosts and target them collectively in tasks.
298
+
299
+ ```ruby
300
+ # Define roles
301
+ role :web, %w[web01 web02 web03]
302
+ role :db, %w[db01 db02]
303
+ role :cache, %w[cache01]
304
+ role :all, %w[web01 web02 web03 db01 db02 cache01]
305
+
306
+ # Use roles in tasks
307
+ task :deploy_web, roles: :web do
308
+ # Executes on all web servers
309
+ end
310
+
311
+ task :backup_db, roles: :db do
312
+ # Executes on all database servers
313
+ end
314
+
315
+ # Multiple roles
316
+ task :deploy_all, roles: [:web, :cache] do
317
+ # Executes on web and cache servers
318
+ end
319
+ ```
320
+
321
+ ### Task Definition
322
+
323
+ #### Basic Task
324
+
325
+ ```ruby
326
+ task :hello do
327
+ run "echo 'Hello, World!'"
328
+ end
329
+ ```
330
+
331
+ #### Role-based Task
332
+
333
+ ```ruby
334
+ task :deploy_web, roles: :web do
335
+ run "sudo systemctl restart nginx"
336
+ end
337
+ ```
338
+
339
+ #### Host-specific Task
340
+
341
+ ```ruby
342
+ task :maintenance, on: %w[web01] do
343
+ run <<~SHELL
344
+ sudo systemctl stop nginx
345
+ sudo apt-get update && sudo apt-get upgrade -y
346
+ sudo systemctl start nginx
347
+ SHELL
348
+ end
349
+ ```
350
+
351
+ #### Task with Multiple Commands
352
+
353
+ ```ruby
354
+ task :deploy, roles: :web do
355
+ # Stop service
356
+ run "sudo systemctl stop nginx"
357
+
358
+ # Upload configuration
359
+ upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
360
+
361
+ # Start service
362
+ run "sudo systemctl start nginx"
363
+
364
+ # Verify status
365
+ run "sudo systemctl status nginx"
366
+ end
367
+ ```
368
+
369
+ #### Task Options
370
+
371
+ | Option | Type | Description |
372
+ |-------|------|-------------|
373
+ | `roles` | Symbol/Array | Execute on hosts with specified role(s) |
374
+ | `on` | Array | Execute on specific host(s) |
375
+
376
+ **Note**: If neither `roles` nor `on` is specified, the task executes on all defined hosts.
377
+
378
+ ### Command Types
379
+
380
+ #### `run` - Execute Shell Commands
381
+
382
+ Execute commands on remote servers.
383
+
384
+ ```ruby
385
+ # Single line command
386
+ run "sudo systemctl restart nginx"
387
+
388
+ # Multi-line command (recommended for complex commands)
389
+ run <<~SHELL
390
+ cd /var/www/app
391
+ git pull origin main
392
+ bundle install
393
+ sudo systemctl restart puma
394
+ SHELL
395
+ ```
396
+
397
+ **Best Practice**: Use heredoc (`<<~SHELL`) for multi-line commands to improve readability.
398
+
399
+ #### `upload` - Upload Files
400
+
401
+ Upload files to remote servers.
402
+
403
+ ```ruby
404
+ upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
405
+ upload "./scripts/deploy.sh", "/tmp/deploy.sh"
406
+ ```
407
+
408
+ **Parameters:**
409
+ - `source`: Local file path
410
+ - `destination`: Remote file path
411
+
412
+ #### `upload_template` - Upload ERB Templates
413
+
414
+ Upload and render ERB templates with variable substitution.
415
+
416
+ ```ruby
417
+ upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
418
+ domain_name: "example.com",
419
+ port: 3000,
420
+ worker_processes: 4
421
+ ```
422
+
423
+ **Parameters:**
424
+ - `source`: Local ERB template file path
425
+ - `destination`: Remote file path
426
+ - `variables`: Hash of variables for template rendering
427
+
428
+ ### Template Support
429
+
430
+ Kdeploy supports ERB (Embedded Ruby) templates for dynamic configuration generation.
431
+
432
+ #### Creating Templates
433
+
434
+ Create an ERB template file (e.g., `config/nginx.conf.erb`):
435
+
436
+ ```erb
437
+ user nginx;
438
+ worker_processes <%= worker_processes %>;
439
+ error_log /var/log/nginx/error.log;
440
+ pid /run/nginx.pid;
441
+
442
+ events {
443
+ worker_connections <%= worker_connections %>;
444
+ }
445
+
446
+ http {
447
+ include /etc/nginx/mime.types;
448
+ default_type application/octet-stream;
449
+
450
+ upstream app_servers {
451
+ server 127.0.0.1:<%= port %>;
452
+ }
453
+
454
+ server {
455
+ listen 80;
456
+ server_name <%= domain_name %>;
457
+
458
+ location / {
459
+ proxy_pass http://app_servers;
460
+ proxy_http_version 1.1;
461
+ proxy_set_header Upgrade $http_upgrade;
462
+ proxy_set_header Connection 'upgrade';
463
+ proxy_set_header Host $host;
464
+ proxy_cache_bypass $http_upgrade;
465
+ }
466
+ }
467
+ }
468
+ ```
469
+
470
+ #### Using Templates
471
+
472
+ ```ruby
473
+ task :deploy_config do
474
+ upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
475
+ domain_name: "example.com",
476
+ port: 3000,
477
+ worker_processes: 4,
478
+ worker_connections: 2048
479
+ end
480
+ ```
481
+
482
+ #### Template Features
483
+
484
+ - Full ERB syntax support
485
+ - Variable substitution
486
+ - Conditional logic
487
+ - Loops and iterations
488
+ - Ruby code execution
489
+
490
+ ### Inventory Block
491
+
492
+ Use the `inventory` block to organize host definitions:
493
+
494
+ ```ruby
495
+ inventory do
496
+ host 'web01', user: 'ubuntu', ip: '10.0.0.1', key: '~/.ssh/id_rsa'
497
+ host 'web02', user: 'ubuntu', ip: '10.0.0.2', key: '~/.ssh/id_rsa'
498
+ host 'db01', user: 'root', ip: '10.0.0.3', key: '~/.ssh/id_rsa'
499
+ end
500
+ ```
501
+
502
+ ## βš™οΈ Configuration
503
+
504
+ ### Default Configuration
505
+
506
+ Kdeploy uses sensible defaults that can be customized:
507
+
508
+ - **Default Parallel Count**: 10 concurrent executions
509
+ - **SSH Timeout**: 30 seconds
510
+ - **Host Key Verification**: Disabled (for convenience, enable in production)
511
+
512
+ ### Environment Variables
513
+
514
+ You can override defaults using environment variables:
515
+
516
+ ```bash
517
+ export KDEPLOY_PARALLEL=5
518
+ export KDEPLOY_SSH_TIMEOUT=60
519
+ ```
520
+
521
+ ### Configuration File
522
+
523
+ For project-specific configuration, create a `.kdeploy.yml`:
524
+
525
+ ```yaml
526
+ parallel: 5
527
+ ssh_timeout: 60
528
+ verify_host_key: true
529
+ ```
530
+
531
+ ## πŸ”§ Advanced Usage
532
+
533
+ ### Conditional Execution
534
+
535
+ Use Ruby conditionals in your deployment files:
536
+
537
+ ```ruby
538
+ task :deploy do
539
+ if ENV['ENVIRONMENT'] == 'production'
540
+ run "sudo systemctl stop nginx"
541
+ end
542
+
543
+ upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
544
+
545
+ if ENV['ENVIRONMENT'] == 'production'
546
+ run "sudo systemctl start nginx"
547
+ end
548
+ end
549
+ ```
550
+
551
+ ### Looping Over Hosts
552
+
553
+ ```ruby
554
+ # Execute different commands based on host
555
+ task :custom_setup do
556
+ @hosts.each do |name, config|
557
+ if name.start_with?('web')
558
+ run "echo 'Web server: #{name}'"
559
+ elsif name.start_with?('db')
560
+ run "echo 'Database server: #{name}'"
561
+ end
562
+ end
563
+ end
564
+ ```
565
+
566
+ ### Error Handling in Tasks
567
+
568
+ ```ruby
569
+ task :deploy do
570
+ run "sudo systemctl stop nginx" || raise "Failed to stop nginx"
571
+ upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
572
+ run "sudo systemctl start nginx" || raise "Failed to start nginx"
573
+ end
574
+ ```
575
+
576
+ ### Using External Libraries
577
+
578
+ ```ruby
579
+ require 'yaml'
580
+ require 'json'
581
+
582
+ # Load configuration from external files
583
+ config = YAML.load_file('config.yml')
584
+
585
+ task :deploy do
586
+ config['commands'].each do |cmd|
587
+ run cmd
588
+ end
589
+ end
590
+ ```
591
+
592
+ ### Task Dependencies
593
+
594
+ While Kdeploy doesn't have built-in task dependencies, you can achieve this with Ruby:
595
+
596
+ ```ruby
597
+ task :setup do
598
+ run "echo 'Setting up...'"
599
+ end
600
+
601
+ task :deploy do
602
+ # Manually call setup task
603
+ self.class.kdeploy_tasks[:setup][:block].call.each do |cmd|
604
+ case cmd[:type]
605
+ when :run
606
+ run cmd[:command]
607
+ when :upload
608
+ upload cmd[:source], cmd[:destination]
609
+ end
610
+ end
611
+
612
+ run "echo 'Deploying...'"
613
+ end
614
+ ```
615
+
616
+ ## 🚨 Error Handling
617
+
618
+ ### Error Types
619
+
620
+ Kdeploy provides specific error types for better debugging:
621
+
622
+ - `Kdeploy::TaskNotFoundError` - Task not found
623
+ - `Kdeploy::HostNotFoundError` - Host not found
624
+ - `Kdeploy::SSHError` - SSH operation failed
625
+ - `Kdeploy::SCPError` - SCP upload failed
626
+ - `Kdeploy::TemplateError` - Template rendering failed
627
+ - `Kdeploy::ConfigurationError` - Configuration error
628
+ - `Kdeploy::FileNotFoundError` - File not found
629
+
630
+ ### Error Output
631
+
632
+ Errors are displayed with:
633
+ - Red color coding
634
+ - Detailed error messages
635
+ - Host information
636
+ - Original error context
637
+
638
+ ### Handling Errors
639
+
640
+ ```ruby
641
+ # In your deployment file
642
+ begin
643
+ task :deploy do
644
+ run "risky-command"
645
+ end
646
+ rescue Kdeploy::SSHError => e
647
+ puts "SSH Error: #{e.message}"
648
+ # Handle error
649
+ end
650
+ ```
651
+
652
+ ## πŸ’‘ Best Practices
653
+
654
+ ### 1. Use Heredoc for Multi-line Commands
655
+
656
+ ```ruby
657
+ # βœ… Good
658
+ run <<~SHELL
659
+ cd /var/www/app
660
+ git pull origin main
661
+ bundle install
662
+ SHELL
663
+
664
+ # ❌ Avoid
665
+ run "cd /var/www/app && git pull origin main && bundle install"
666
+ ```
667
+
668
+ ### 2. Organize with Roles
669
+
670
+ ```ruby
671
+ # βœ… Good - Use roles for organization
672
+ role :web, %w[web01 web02]
673
+ role :db, %w[db01 db02]
674
+
675
+ task :deploy_web, roles: :web do
676
+ # ...
677
+ end
678
+
679
+ # ❌ Avoid - Hardcoding host names
680
+ task :deploy do
681
+ # Hard to maintain
682
+ end
683
+ ```
684
+
685
+ ### 3. Use Templates for Dynamic Configuration
686
+
687
+ ```ruby
688
+ # βœ… Good - Use templates
689
+ upload_template "./config/nginx.conf.erb", "/etc/nginx/nginx.conf",
690
+ domain_name: "example.com",
691
+ port: 3000
692
+
693
+ # ❌ Avoid - Hardcoding values
694
+ run "echo 'server_name example.com;' > /etc/nginx/nginx.conf"
695
+ ```
696
+
697
+ ### 4. Validate Before Deployment
698
+
699
+ ```ruby
700
+ task :deploy do
701
+ # Validate configuration
702
+ run "nginx -t" || raise "Nginx configuration is invalid"
703
+
704
+ # Deploy
705
+ upload "./config/nginx.conf", "/etc/nginx/nginx.conf"
706
+ run "sudo systemctl reload nginx"
707
+ end
708
+ ```
709
+
710
+ ### 5. Use Dry Run for Testing
711
+
712
+ Always test with `--dry-run` before actual deployment:
713
+
714
+ ```bash
715
+ kdeploy execute deploy.rb deploy_web --dry-run
716
+ ```
717
+
718
+ ### 6. Organize Files Properly
719
+
720
+ ```
721
+ project/
722
+ β”œβ”€β”€ deploy.rb # Main deployment file
723
+ β”œβ”€β”€ config/ # Configuration files
724
+ β”‚ β”œβ”€β”€ nginx.conf.erb # Templates
725
+ β”‚ └── app.conf # Static configs
726
+ └── scripts/ # Helper scripts
727
+ └── deploy.sh
728
+ ```
729
+
730
+ ### 7. Version Control
731
+
732
+ - Commit `deploy.rb` and templates
733
+ - Use `.gitignore` for sensitive files
734
+ - Store secrets in environment variables
735
+
736
+ ### 8. Parallel Execution
737
+
738
+ Adjust parallel count based on your infrastructure:
739
+
740
+ ```bash
741
+ # For many hosts, increase parallel count
742
+ kdeploy execute deploy.rb deploy --parallel 20
743
+
744
+ # For limited resources, decrease
745
+ kdeploy execute deploy.rb deploy --parallel 3
746
+ ```
747
+
748
+ ## πŸ” Troubleshooting
749
+
750
+ ### Common Issues
751
+
752
+ #### SSH Authentication Failed
753
+
754
+ **Problem**: `SSH authentication failed`
755
+
756
+ **Solutions**:
757
+ 1. Verify SSH key path is correct
758
+ 2. Check key permissions: `chmod 600 ~/.ssh/id_rsa`
759
+ 3. Test SSH connection manually: `ssh user@host`
760
+ 4. Verify username and IP address
761
+
762
+ #### Host Not Found
763
+
764
+ **Problem**: `No hosts found for task`
765
+
766
+ **Solutions**:
767
+ 1. Verify host names in task match defined hosts
768
+ 2. Check role definitions
769
+ 3. Verify `--limit` option if used
770
+
771
+ #### Command Execution Failed
772
+
773
+ **Problem**: Commands fail on remote server
774
+
775
+ **Solutions**:
776
+ 1. Test commands manually on target server
777
+ 2. Check user permissions (may need sudo)
778
+ 3. Verify command syntax
779
+ 4. Check server logs
780
+
781
+ #### Template Rendering Error
782
+
783
+ **Problem**: Template upload fails
784
+
785
+ **Solutions**:
786
+ 1. Verify ERB syntax in template
787
+ 2. Check all required variables are provided
788
+ 3. Validate template file exists
789
+ 4. Test template rendering locally
790
+
791
+ #### Connection Timeout
792
+
793
+ **Problem**: SSH connection times out
794
+
795
+ **Solutions**:
796
+ 1. Check network connectivity
797
+ 2. Verify firewall rules
798
+ 3. Increase timeout in configuration
799
+ 4. Check SSH service on target server
800
+
801
+ ### Debug Mode
802
+
803
+ Enable verbose output by checking the execution output. Kdeploy provides detailed information about:
804
+ - Task execution status
805
+ - Command output
806
+ - Error messages
807
+ - Execution duration
808
+
809
+ ### Getting Help
810
+
811
+ - Check [GitHub Issues](https://github.com/kevin197011/kdeploy/issues)
812
+ - Review example projects
813
+ - Read the documentation
814
+ - Ask in discussions
815
+
816
+ ## πŸ—οΈ Architecture
817
+
818
+ ### Core Components
819
+
820
+ - **CLI** (`cli.rb`): Command-line interface using Thor
821
+ - **DSL** (`dsl.rb`): Domain-specific language for task definition
822
+ - **Executor** (`executor.rb`): SSH/SCP execution engine
823
+ - **Runner** (`runner.rb`): Concurrent task execution coordinator
824
+ - **CommandExecutor** (`command_executor.rb`): Individual command execution
825
+ - **CommandGrouper** (`command_grouper.rb`): Command grouping logic
826
+ - **Template** (`template.rb`): ERB template rendering
827
+ - **Output** (`output.rb`): Output formatting and display
828
+ - **Configuration** (`configuration.rb`): Configuration management
829
+ - **Errors** (`errors.rb`): Custom error types
830
+
831
+ ### Execution Flow
832
+
833
+ 1. **Parse Configuration**: Load and parse `deploy.rb`
834
+ 2. **Resolve Hosts**: Determine target hosts based on task definition
835
+ 3. **Group Commands**: Group commands by type for efficient execution
836
+ 4. **Execute Concurrently**: Run tasks in parallel across hosts
837
+ 5. **Collect Results**: Gather execution results and status
838
+ 6. **Display Output**: Format and display results to user
839
+
840
+ ### Concurrency Model
841
+
842
+ Kdeploy uses `concurrent-ruby` with a fixed thread pool:
843
+ - Default: 10 concurrent executions
844
+ - Configurable via `--parallel` option
845
+ - Thread-safe result collection
846
+ - Automatic resource cleanup
847
+
848
+ ## πŸ”§ Development
849
+
850
+ ### Setup Development Environment
851
+
852
+ ```bash
853
+ # Clone repository
854
+ git clone https://github.com/kevin197011/kdeploy.git
855
+ cd kdeploy
856
+
857
+ # Install dependencies
858
+ bundle install
859
+
860
+ # Run tests
861
+ bundle exec rspec
862
+
863
+ # Run console
864
+ bin/console
865
+ ```
866
+
867
+ ### Project Structure
868
+
869
+ ```
870
+ kdeploy/
871
+ β”œβ”€β”€ lib/
872
+ β”‚ └── kdeploy/
873
+ β”‚ β”œβ”€β”€ cli.rb # CLI interface
874
+ β”‚ β”œβ”€β”€ dsl.rb # DSL definition
875
+ β”‚ β”œβ”€β”€ executor.rb # SSH/SCP executor
876
+ β”‚ β”œβ”€β”€ runner.rb # Task runner
877
+ β”‚ β”œβ”€β”€ command_executor.rb # Command executor
878
+ β”‚ β”œβ”€β”€ command_grouper.rb # Command grouper
879
+ β”‚ β”œβ”€β”€ template.rb # Template handler
880
+ β”‚ β”œβ”€β”€ output.rb # Output interface
881
+ β”‚ β”œβ”€β”€ configuration.rb # Configuration
882
+ β”‚ β”œβ”€β”€ errors.rb # Error types
883
+ β”‚ └── ...
884
+ β”œβ”€β”€ spec/ # Tests
885
+ β”œβ”€β”€ exe/ # Executables
886
+ β”œβ”€β”€ sample/ # Example projects
887
+ └── README.md # This file
888
+ ```
889
+
890
+ ### Running Tests
891
+
892
+ ```bash
893
+ # Run all tests
894
+ bundle exec rspec
895
+
896
+ # Run specific test file
897
+ bundle exec rspec spec/kdeploy_spec.rb
898
+
899
+ # Run with coverage
900
+ COVERAGE=true bundle exec rspec
901
+ ```
902
+
903
+ ### Building the Gem
904
+
905
+ ```bash
906
+ # Build gem
907
+ gem build kdeploy.gemspec
908
+
909
+ # Install locally
910
+ gem install ./kdeploy-*.gem
911
+ ```
912
+
913
+ ### Code Style
914
+
915
+ The project uses RuboCop for code style:
916
+
917
+ ```bash
918
+ # Check style
919
+ bundle exec rubocop
920
+
921
+ # Auto-fix issues
922
+ bundle exec rubocop -a
923
+ ```
924
+
925
+ ## 🀝 Contributing
926
+
927
+ Contributions are welcome! Please follow these steps:
928
+
929
+ 1. **Fork the repository**
930
+ 2. **Create a feature branch**: `git checkout -b feature/my-new-feature`
931
+ 3. **Make your changes**: Follow the code style and add tests
932
+ 4. **Commit your changes**: Use conventional commit messages
933
+ 5. **Push to the branch**: `git push origin feature/my-new-feature`
934
+ 6. **Create a Pull Request**: Provide a clear description of changes
935
+
936
+ ### Contribution Guidelines
937
+
938
+ - Follow existing code style
939
+ - Add tests for new features
940
+ - Update documentation
941
+ - Ensure all tests pass
942
+ - Follow conventional commit format
943
+
944
+ ### Commit Message Format
945
+
946
+ Follow [Conventional Commits](https://www.conventionalcommits.org/):
947
+
948
+ ```
949
+ <type>(<scope>): <subject>
950
+
951
+ <body>
952
+
953
+ <footer>
954
+ ```
955
+
956
+ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
957
+
958
+ ## πŸ“š Examples
959
+
960
+ ### Example Projects
961
+
962
+ Check out the [example project](https://github.com/kevin197011/kdeploy-app) for a complete deployment setup.
963
+
964
+ ### Common Deployment Scenarios
965
+
966
+ #### Web Application Deployment
967
+
968
+ ```ruby
969
+ host "web01", user: "deploy", ip: "10.0.0.1", key: "~/.ssh/id_rsa"
970
+ role :web, %w[web01]
971
+
972
+ task :deploy_app, roles: :web do
973
+ run <<~SHELL
974
+ cd /var/www/app
975
+ git pull origin main
976
+ bundle install
977
+ rake db:migrate
978
+ sudo systemctl restart puma
979
+ SHELL
980
+ end
981
+ ```
982
+
983
+ #### Database Backup
984
+
985
+ ```ruby
986
+ host "db01", user: "postgres", ip: "10.0.0.10", key: "~/.ssh/id_rsa"
987
+ role :db, %w[db01]
988
+
989
+ task :backup, roles: :db do
990
+ run <<~SHELL
991
+ pg_dump mydb > /tmp/backup_$(date +%Y%m%d).sql
992
+ gzip /tmp/backup_*.sql
993
+ aws s3 cp /tmp/backup_*.sql.gz s3://backups/
994
+ rm /tmp/backup_*.sql.gz
995
+ SHELL
996
+ end
997
+ ```
998
+
999
+ #### Configuration Management
1000
+
1001
+ ```ruby
1002
+ task :update_config, roles: :web do
1003
+ upload_template "./config/app.yml.erb", "/etc/app/config.yml",
1004
+ environment: "production",
1005
+ database_url: ENV['DATABASE_URL'],
1006
+ redis_url: ENV['REDIS_URL']
1007
+
1008
+ run "sudo systemctl reload app"
1009
+ end
1010
+ ```
1011
+
1012
+ ## πŸ“ License
1013
+
1014
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
1015
+
1016
+ ## πŸ”— Links
1017
+
1018
+ - **GitHub**: https://github.com/kevin197011/kdeploy
1019
+ - **RubyGems**: https://rubygems.org/gems/kdeploy
1020
+ - **Issues**: https://github.com/kevin197011/kdeploy/issues
1021
+ - **Example Project**: https://github.com/kevin197011/kdeploy-app
1022
+
1023
+ ## πŸ™ Acknowledgments
1024
+
1025
+ - Built with [Thor](https://github.com/rails/thor) for CLI
1026
+ - Uses [net-ssh](https://github.com/net-ssh/net-ssh) for SSH operations
1027
+ - Powered by [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) for concurrency
1028
+
1029
+ ---
1030
+
1031
+ **Made with ❀️ for the DevOps community**