Class: Kdeploy::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/kdeploy/dsl.rb

Overview

Domain Specific Language for deployment scripts

Instance Method Summary collapse

Constructor Details

#initialize(script_dir = nil) ⇒ DSL

Returns a new instance of DSL.



6
7
8
9
10
11
12
# File 'lib/kdeploy/dsl.rb', line 6

def initialize(script_dir = nil)
  @pipeline = Pipeline.new
  @current_task = nil
  @inventory = nil
  @script_dir = script_dir || Dir.pwd
  @template_manager = nil
end

Instance Method Details

#download(remote_path, local_path, name: nil) ⇒ Command

Download file from remote host

Parameters:

  • remote_path (String)

    Remote file path

  • local_path (String)

    Local file path

  • name (String) (defaults to: nil)

    Command name (optional)

Returns:

  • (Command)

    Created download command



173
174
175
176
177
178
# File 'lib/kdeploy/dsl.rb', line 173

def download(remote_path, local_path, name: nil)
  raise 'download can only be called within a task block' unless @current_task

  command_name = name || "download_#{File.basename(remote_path)}"
  add_download_command(remote_path, local_path, command_name)
end

#host(hostname, user: nil, port: nil, roles: [], vars: {}, **ssh_options) ⇒ Host

Define host

Parameters:

  • hostname (String)

    Hostname or IP address

  • user (String) (defaults to: nil)

    SSH user

  • port (Integer) (defaults to: nil)

    SSH port

  • roles (Array) (defaults to: [])

    Host roles

  • vars (Hash) (defaults to: {})

    Host variables

  • ssh_options (Hash)

    SSH connection options

Returns:

  • (Host)

    Created host



37
38
39
40
41
42
43
44
45
46
# File 'lib/kdeploy/dsl.rb', line 37

def host(hostname, user: nil, port: nil, roles: [], vars: {}, **ssh_options)
  @pipeline.add_host(
    hostname,
    user: user,
    port: port,
    roles: roles,
    vars: vars,
    ssh_options: ssh_options
  )
end

#hosts(hosts_config) ⇒ Object

Define multiple hosts

Parameters:

  • hosts_config (Hash)

    Hosts configuration



50
51
52
# File 'lib/kdeploy/dsl.rb', line 50

def hosts(hosts_config)
  @pipeline.add_hosts(hosts_config)
end

#include(script_path) ⇒ Object

Include external script

Parameters:

  • script_path (String)

    Path to script file



203
204
205
206
207
208
# File 'lib/kdeploy/dsl.rb', line 203

def include(script_path)
  return unless File.exist?(script_path)

  script_content = File.read(script_path)
  instance_eval(script_content, script_path)
end

#inventory(inventory_file = nil) ⇒ Object

Load hosts from inventory file

Parameters:

  • inventory_file (String) (defaults to: nil)

    Path to inventory file



56
57
58
59
60
61
62
63
# File 'lib/kdeploy/dsl.rb', line 56

def inventory(inventory_file = nil)
  inventory_file ||= default_inventory_file
  resolved_path = resolve_inventory_path(inventory_file)

  return unless File.exist?(resolved_path)

  load_inventory(resolved_path)
end

#local(command, name: nil) ⇒ Array<Hash>

Execute local command

Parameters:

  • command (String)

    Local command to execute

  • name (String) (defaults to: nil)

    Command name (optional)

Returns:

  • (Array<Hash>)

    Command results



133
134
135
136
137
138
139
# File 'lib/kdeploy/dsl.rb', line 133

def local(command, name: nil)
  require 'open3'

  process_commands(command, name).map do |cmd_name, cmd|
    execute_local_command(cmd, cmd_name)
  end
end

#pipeline(name = nil) ⇒ Pipeline

Get pipeline or set pipeline name

Parameters:

  • name (String) (defaults to: nil)

    Pipeline name (optional)

Returns:



17
18
19
20
# File 'lib/kdeploy/dsl.rb', line 17

def pipeline(name = nil)
  @pipeline.instance_variable_set(:@name, name) if name
  @pipeline
end

#role(role) ⇒ Array<Host>

Get hosts by role

Parameters:

  • role (String, Symbol)

    Role to filter by

Returns:

  • (Array<Host>)

    Hosts with specified role



183
184
185
# File 'lib/kdeploy/dsl.rb', line 183

def role(role)
  @pipeline.hosts_with_role(role)
end

#run(command, name: nil, timeout: nil, retry_count: nil, retry_delay: nil, ignore_errors: false, only: nil, except: nil) ⇒ Array<Command>

Execute command in current task

Parameters:

  • command (String)

    Command to execute (supports heredoc)

  • name (String) (defaults to: nil)

    Command name (optional)

  • timeout (Integer) (defaults to: nil)

    Command timeout

  • retry_count (Integer) (defaults to: nil)

    Number of retries

  • retry_delay (Integer) (defaults to: nil)

    Delay between retries

  • ignore_errors (Boolean) (defaults to: false)

    Continue on error

  • only (Array, Symbol) (defaults to: nil)

    Run only on specified roles

  • except (Array, Symbol) (defaults to: nil)

    Skip specified roles

Returns:

  • (Array<Command>)

    Created commands



117
118
119
120
121
122
123
124
125
126
127
# File 'lib/kdeploy/dsl.rb', line 117

def run(command, name: nil, timeout: nil, retry_count: nil, retry_delay: nil,
        ignore_errors: false, only: nil, except: nil)
  raise 'run can only be called within a task block' unless @current_task

  process_commands(command, name).each_with_object([]) do |(cmd_name, cmd), commands|
    commands << add_command_to_task(
      cmd_name, cmd, timeout, retry_count, retry_delay,
      ignore_errors, only, except
    )
  end
end

#set(key, value) ⇒ Object

Set global variable

Parameters:

  • key (String, Symbol)

    Variable key

  • value (Object)

    Variable value



25
26
27
# File 'lib/kdeploy/dsl.rb', line 25

def set(key, value)
  @pipeline.set_variable(key, value)
end

#task(name, on: nil, parallel: true, fail_fast: false, max_concurrent: nil, &block) ⇒ Task

Define task

Parameters:

  • name (String)

    Task name

  • on (Array, Symbol) (defaults to: nil)

    Target hosts or roles

  • parallel (Boolean) (defaults to: true)

    Execute in parallel

  • fail_fast (Boolean) (defaults to: false)

    Stop on first failure

  • max_concurrent (Integer) (defaults to: nil)

    Maximum concurrent executions

Returns:

  • (Task)

    Created task



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/kdeploy/dsl.rb', line 92

def task(name, on: nil, parallel: true, fail_fast: false, max_concurrent: nil, &block)
  target_hosts = resolve_target_hosts(on)

  @current_task = @pipeline.add_task(
    name,
    hosts: target_hosts,
    parallel: parallel,
    fail_fast: fail_fast,
    max_concurrent: max_concurrent
  )

  instance_eval(&block) if block
  @current_task = nil
end

#template_dir(template_dir = nil) ⇒ Object

Initialize template manager

Parameters:

  • template_dir (String) (defaults to: nil)

    Template directory path



67
68
69
70
71
72
73
# File 'lib/kdeploy/dsl.rb', line 67

def template_dir(template_dir = nil)
  template_dir ||= default_template_dir
  resolved_path = resolve_template_path(template_dir)

  @template_manager = TemplateManager.new(resolved_path, @pipeline.variables)
  KdeployLogger.info("Template directory set to: #{resolved_path}")
end

#template_managerTemplateManager

Get or initialize template manager

Returns:



77
78
79
80
81
82
83
# File 'lib/kdeploy/dsl.rb', line 77

def template_manager
  @template_manager ||= begin
    dir = default_template_dir
    resolved_path = resolve_template_path(dir)
    TemplateManager.new(resolved_path, @pipeline.variables)
  end
end

#unless(condition) { ... } ⇒ Object

Inverse conditional execution

Parameters:

  • condition (Boolean)

    Condition to check

Yields:

  • Block to execute if condition is false



197
198
199
# File 'lib/kdeploy/dsl.rb', line 197

def unless(condition, &)
  instance_eval(&) if !condition && block_given?
end

#upload(local_path, remote_path, name: nil) ⇒ Command

Upload file to remote host

Parameters:

  • local_path (String)

    Local file path

  • remote_path (String)

    Remote file path

  • name (String) (defaults to: nil)

    Command name (optional)

Returns:

  • (Command)

    Created upload command



146
147
148
149
150
151
152
# File 'lib/kdeploy/dsl.rb', line 146

def upload(local_path, remote_path, name: nil)
  raise 'upload can only be called within a task block' unless @current_task

  ensure_remote_directory(remote_path)
  command_name = name || "upload_#{File.basename(local_path)}"
  add_upload_command(local_path, remote_path, command_name)
end

#upload_template(template_name, remote_path, variables: {}, name: nil) ⇒ Command

Upload template to remote host

Parameters:

  • template_name (String)

    Template name

  • remote_path (String)

    Remote file path

  • variables (Hash) (defaults to: {})

    Template variables

  • name (String) (defaults to: nil)

    Command name (optional)

Returns:

  • (Command)

    Created template upload command



160
161
162
163
164
165
166
# File 'lib/kdeploy/dsl.rb', line 160

def upload_template(template_name, remote_path, variables: {}, name: nil)
  raise 'upload_template can only be called within a task block' unless @current_task

  ensure_remote_directory(remote_path)
  command_name = name || "upload_template_#{File.basename(template_name)}"
  add_template_upload_command(template_name, remote_path, variables, command_name)
end

#when(condition) { ... } ⇒ Object

Conditional execution

Parameters:

  • condition (Boolean)

    Condition to check

Yields:

  • Block to execute if condition is true



190
191
192
# File 'lib/kdeploy/dsl.rb', line 190

def when(condition, &)
  instance_eval(&) if condition && block_given?
end