bosh_cli 0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/README +4 -0
- data/Rakefile +55 -0
- data/bin/bosh +17 -0
- data/lib/cli.rb +76 -0
- data/lib/cli/cache.rb +44 -0
- data/lib/cli/changeset_helper.rb +142 -0
- data/lib/cli/command_definition.rb +52 -0
- data/lib/cli/commands/base.rb +245 -0
- data/lib/cli/commands/biff.rb +300 -0
- data/lib/cli/commands/blob.rb +125 -0
- data/lib/cli/commands/cloudcheck.rb +169 -0
- data/lib/cli/commands/deployment.rb +147 -0
- data/lib/cli/commands/job.rb +42 -0
- data/lib/cli/commands/job_management.rb +117 -0
- data/lib/cli/commands/log_management.rb +81 -0
- data/lib/cli/commands/maintenance.rb +131 -0
- data/lib/cli/commands/misc.rb +240 -0
- data/lib/cli/commands/package.rb +112 -0
- data/lib/cli/commands/property_management.rb +125 -0
- data/lib/cli/commands/release.rb +469 -0
- data/lib/cli/commands/ssh.rb +271 -0
- data/lib/cli/commands/stemcell.rb +184 -0
- data/lib/cli/commands/task.rb +213 -0
- data/lib/cli/commands/user.rb +28 -0
- data/lib/cli/commands/vms.rb +53 -0
- data/lib/cli/config.rb +154 -0
- data/lib/cli/core_ext.rb +145 -0
- data/lib/cli/dependency_helper.rb +62 -0
- data/lib/cli/deployment_helper.rb +263 -0
- data/lib/cli/deployment_manifest_compiler.rb +28 -0
- data/lib/cli/director.rb +633 -0
- data/lib/cli/director_task.rb +64 -0
- data/lib/cli/errors.rb +48 -0
- data/lib/cli/event_log_renderer.rb +351 -0
- data/lib/cli/job_builder.rb +226 -0
- data/lib/cli/package_builder.rb +254 -0
- data/lib/cli/packaging_helper.rb +248 -0
- data/lib/cli/release.rb +176 -0
- data/lib/cli/release_builder.rb +215 -0
- data/lib/cli/release_compiler.rb +178 -0
- data/lib/cli/release_tarball.rb +272 -0
- data/lib/cli/runner.rb +771 -0
- data/lib/cli/stemcell.rb +83 -0
- data/lib/cli/task_log_renderer.rb +40 -0
- data/lib/cli/templates/help_message.erb +75 -0
- data/lib/cli/validation.rb +42 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/version_calc.rb +48 -0
- data/lib/cli/versions_index.rb +126 -0
- data/lib/cli/yaml_helper.rb +62 -0
- data/spec/assets/biff/bad_gateway_config.yml +28 -0
- data/spec/assets/biff/good_simple_config.yml +63 -0
- data/spec/assets/biff/good_simple_golden_config.yml +63 -0
- data/spec/assets/biff/good_simple_template.erb +69 -0
- data/spec/assets/biff/multiple_subnets_config.yml +40 -0
- data/spec/assets/biff/network_only_template.erb +34 -0
- data/spec/assets/biff/no_cc_config.yml +27 -0
- data/spec/assets/biff/no_range_config.yml +27 -0
- data/spec/assets/biff/no_subnet_config.yml +16 -0
- data/spec/assets/biff/ok_network_config.yml +30 -0
- data/spec/assets/biff/properties_template.erb +6 -0
- data/spec/assets/deployment.MF +0 -0
- data/spec/assets/plugins/bosh/cli/commands/echo.rb +43 -0
- data/spec/assets/plugins/bosh/cli/commands/ruby.rb +24 -0
- data/spec/assets/release/jobs/cacher.tgz +0 -0
- data/spec/assets/release/jobs/cacher/config/file1.conf +0 -0
- data/spec/assets/release/jobs/cacher/config/file2.conf +0 -0
- data/spec/assets/release/jobs/cacher/job.MF +6 -0
- data/spec/assets/release/jobs/cacher/monit +1 -0
- data/spec/assets/release/jobs/cleaner.tgz +0 -0
- data/spec/assets/release/jobs/cleaner/job.MF +4 -0
- data/spec/assets/release/jobs/cleaner/monit +1 -0
- data/spec/assets/release/jobs/sweeper.tgz +0 -0
- data/spec/assets/release/jobs/sweeper/config/test.conf +1 -0
- data/spec/assets/release/jobs/sweeper/job.MF +5 -0
- data/spec/assets/release/jobs/sweeper/monit +1 -0
- data/spec/assets/release/packages/mutator.tar.gz +0 -0
- data/spec/assets/release/packages/stuff.tgz +0 -0
- data/spec/assets/release/release.MF +17 -0
- data/spec/assets/release_invalid_checksum.tgz +0 -0
- data/spec/assets/release_invalid_jobs.tgz +0 -0
- data/spec/assets/release_no_name.tgz +0 -0
- data/spec/assets/release_no_version.tgz +0 -0
- data/spec/assets/stemcell/image +1 -0
- data/spec/assets/stemcell/stemcell.MF +6 -0
- data/spec/assets/stemcell_invalid_mf.tgz +0 -0
- data/spec/assets/stemcell_no_image.tgz +0 -0
- data/spec/assets/valid_release.tgz +0 -0
- data/spec/assets/valid_stemcell.tgz +0 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/unit/base_command_spec.rb +66 -0
- data/spec/unit/biff_spec.rb +135 -0
- data/spec/unit/cache_spec.rb +36 -0
- data/spec/unit/cli_commands_spec.rb +481 -0
- data/spec/unit/config_spec.rb +139 -0
- data/spec/unit/core_ext_spec.rb +77 -0
- data/spec/unit/dependency_helper_spec.rb +52 -0
- data/spec/unit/deployment_manifest_compiler_spec.rb +63 -0
- data/spec/unit/director_spec.rb +511 -0
- data/spec/unit/director_task_spec.rb +48 -0
- data/spec/unit/event_log_renderer_spec.rb +171 -0
- data/spec/unit/hash_changeset_spec.rb +73 -0
- data/spec/unit/job_builder_spec.rb +454 -0
- data/spec/unit/package_builder_spec.rb +567 -0
- data/spec/unit/release_builder_spec.rb +65 -0
- data/spec/unit/release_spec.rb +66 -0
- data/spec/unit/release_tarball_spec.rb +33 -0
- data/spec/unit/runner_spec.rb +140 -0
- data/spec/unit/ssh_spec.rb +78 -0
- data/spec/unit/stemcell_spec.rb +17 -0
- data/spec/unit/version_calc_spec.rb +27 -0
- data/spec/unit/versions_index_spec.rb +132 -0
- metadata +338 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli::Command
|
4
|
+
class Task < Base
|
5
|
+
|
6
|
+
# Tracks a running task or outputs the logs from an old task. Triggered
|
7
|
+
# with 'bosh task <task_num>'. Check parse_flags to see what flags can be
|
8
|
+
# used with this.
|
9
|
+
#
|
10
|
+
# @param [Array] args The arguments from the command line command.
|
11
|
+
def track(*args)
|
12
|
+
auth_required
|
13
|
+
|
14
|
+
task_id, log_type, no_cache, raw_output = parse_flags(args)
|
15
|
+
|
16
|
+
err("Task id must be a positive integer") unless task_id.to_i > 0
|
17
|
+
|
18
|
+
task = Bosh::Cli::DirectorTask.new(director, task_id, log_type)
|
19
|
+
say("Task state: #{task.state}")
|
20
|
+
|
21
|
+
cached_output = get_cached_task_output(task_id, log_type) unless no_cache
|
22
|
+
|
23
|
+
if raw_output
|
24
|
+
renderer = Bosh::Cli::TaskLogRenderer.new
|
25
|
+
else
|
26
|
+
renderer = Bosh::Cli::TaskLogRenderer.create_for_log_type(log_type)
|
27
|
+
renderer.time_adjustment = director.get_time_difference
|
28
|
+
end
|
29
|
+
|
30
|
+
say("Task log:")
|
31
|
+
|
32
|
+
if cached_output
|
33
|
+
renderer.add_output(cached_output)
|
34
|
+
# renderer.finish calls render which prints the output.
|
35
|
+
renderer.finish(task.state)
|
36
|
+
else
|
37
|
+
# This calls renderer.finish which calls render and prints the output.
|
38
|
+
fetch_print_and_save_output(task, task_id, log_type, renderer)
|
39
|
+
end
|
40
|
+
|
41
|
+
nl
|
42
|
+
|
43
|
+
print_task_state_and_timing(task, task_id, renderer)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Whether the bosh user has asked for the last (most recently run) task.
|
47
|
+
#
|
48
|
+
# @param [String] task_id The task id specified by the user. Could be a
|
49
|
+
# number as a string or it could be "last" or "latest".
|
50
|
+
# @return [Boolean] Whether the user is asking for the most recent task.
|
51
|
+
def asking_for_last_task?(task_id)
|
52
|
+
task_id.nil? || ["last", "latest"].include?(task_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the task id of the most recently run task.
|
56
|
+
#
|
57
|
+
# @return [String] The task id of the most recently run task.
|
58
|
+
def get_last_task_id
|
59
|
+
last = director.list_recent_tasks(1)
|
60
|
+
if last.size == 0
|
61
|
+
err("No tasks found")
|
62
|
+
end
|
63
|
+
|
64
|
+
last[0]["id"]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns what type of log output the user is asking for.
|
68
|
+
#
|
69
|
+
# @param [Array] flags The args that were passed in from the command line.
|
70
|
+
# @return [String] The type of log output the user is asking for.
|
71
|
+
def get_log_type(flags)
|
72
|
+
if flags.include?("--soap")
|
73
|
+
"soap"
|
74
|
+
elsif flags.include?("--event")
|
75
|
+
"event"
|
76
|
+
else
|
77
|
+
"debug"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Parses the command line args to see what options have been specified.
|
82
|
+
#
|
83
|
+
# @param [Array] flags The args that were passed in from the command line.
|
84
|
+
# @return [String, String, Boolean, Boolean] The task id, the type of log
|
85
|
+
# output, whether to use cache or not, whether to output the raw log.
|
86
|
+
def parse_flags(flags)
|
87
|
+
task_id = flags.shift
|
88
|
+
task_id = get_last_task_id if asking_for_last_task?(task_id)
|
89
|
+
|
90
|
+
log_type = get_log_type(flags)
|
91
|
+
|
92
|
+
no_cache = flags.include?("--no-cache")
|
93
|
+
|
94
|
+
raw_output = flags.include?("--raw")
|
95
|
+
|
96
|
+
[task_id, log_type, no_cache, raw_output]
|
97
|
+
end
|
98
|
+
|
99
|
+
# Grabs the log output for a task, prints it, then saves it to the cache.
|
100
|
+
#
|
101
|
+
# @param [Bosh::Cli::DirectorTask] task The director task that has all of
|
102
|
+
# the methods for retrieving/parsing the director's task JSON.
|
103
|
+
# @param [String] task_id The ID of the task to get logs on.
|
104
|
+
# @param [String] log_type The type of log output.
|
105
|
+
# @param [Bosh::Cli::TaskLogRenderer] renderer The renderer that renders the
|
106
|
+
# parsed task JSON.
|
107
|
+
def fetch_print_and_save_output(task, task_id, log_type, renderer)
|
108
|
+
complete_output = ""
|
109
|
+
|
110
|
+
begin
|
111
|
+
state, output = task.state, task.output
|
112
|
+
|
113
|
+
if output
|
114
|
+
renderer.add_output(output)
|
115
|
+
complete_output << output
|
116
|
+
end
|
117
|
+
|
118
|
+
renderer.refresh
|
119
|
+
sleep(0.5)
|
120
|
+
|
121
|
+
end while ["queued", "processing", "cancelling"].include?(state)
|
122
|
+
|
123
|
+
final_out = task.flush_output
|
124
|
+
|
125
|
+
if final_out
|
126
|
+
renderer.add_output(final_out)
|
127
|
+
complete_output << final_out << "\n"
|
128
|
+
end
|
129
|
+
|
130
|
+
renderer.finish(state)
|
131
|
+
save_task_output(task_id, log_type, complete_output)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Prints the task state and timing information at the end of the output.
|
135
|
+
#
|
136
|
+
# @param [Bosh::Cli::DirectorTask] task The director task that has all of
|
137
|
+
# the methods for retrieving/parsing the director's task JSON.
|
138
|
+
# @param [String] task_id The ID of the task to get logs on.
|
139
|
+
# @param [Bosh::Cli::TaskLogRenderer] renderer The renderer that renders the
|
140
|
+
# parsed task JSON.
|
141
|
+
def print_task_state_and_timing(task, task_id, renderer)
|
142
|
+
final_state = task.state
|
143
|
+
color = {
|
144
|
+
"done" => :green,
|
145
|
+
"error" => :red,
|
146
|
+
}[final_state] || :yellow
|
147
|
+
status = "Task %s state is %s" %
|
148
|
+
[task_id.to_s.green, final_state.colorize(color)]
|
149
|
+
|
150
|
+
duration = renderer.duration
|
151
|
+
if final_state == "done" && duration && duration.kind_of?(Numeric)
|
152
|
+
status += ", started: %s, ended: %s (%s)" %
|
153
|
+
[renderer.started_at.to_s.green, renderer.finished_at.to_s.green,
|
154
|
+
format_time(duration).green]
|
155
|
+
end
|
156
|
+
|
157
|
+
say(status)
|
158
|
+
end
|
159
|
+
|
160
|
+
def list_running
|
161
|
+
auth_required
|
162
|
+
tasks = director.list_running_tasks
|
163
|
+
err("No running tasks") if tasks.empty?
|
164
|
+
show_tasks_table(tasks.sort_by { |t| t["id"].to_i * -1 })
|
165
|
+
say("Total tasks running now: %d" % [tasks.size])
|
166
|
+
end
|
167
|
+
|
168
|
+
def list_recent(count = 30)
|
169
|
+
auth_required
|
170
|
+
tasks = director.list_recent_tasks(count)
|
171
|
+
err("No recent tasks") if tasks.empty?
|
172
|
+
show_tasks_table(tasks)
|
173
|
+
say("Showing %d recent %s" % [tasks.size,
|
174
|
+
tasks.size == 1 ? "task" : "tasks"])
|
175
|
+
end
|
176
|
+
|
177
|
+
def cancel(task_id)
|
178
|
+
task = Bosh::Cli::DirectorTask.new(director, task_id)
|
179
|
+
task.cancel
|
180
|
+
say("Cancelling task #{task_id}")
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def show_tasks_table(tasks)
|
186
|
+
return if tasks.empty?
|
187
|
+
tasks_table = table do |t|
|
188
|
+
t.headings = "#", "State", "Timestamp", "Description", "Result"
|
189
|
+
tasks.map do |task|
|
190
|
+
t << [task["id"], task["state"], Time.at(task["timestamp"]).utc,
|
191
|
+
task["description"].to_s, task["result"].to_s.truncate(80)]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
say("\n")
|
196
|
+
say(tasks_table)
|
197
|
+
say("\n")
|
198
|
+
end
|
199
|
+
|
200
|
+
def get_cached_task_output(task_id, log_type)
|
201
|
+
cache.read(task_cache_key(task_id, log_type))
|
202
|
+
end
|
203
|
+
|
204
|
+
def save_task_output(task_id, log_type, output)
|
205
|
+
cache.write(task_cache_key(task_id, log_type), output)
|
206
|
+
end
|
207
|
+
|
208
|
+
def task_cache_key(task_id, log_type)
|
209
|
+
"task/#{target}/#{task_id}/#{log_type}"
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli::Command
|
4
|
+
class User < Base
|
5
|
+
|
6
|
+
def create(username = nil, password = nil)
|
7
|
+
auth_required
|
8
|
+
|
9
|
+
unless options[:non_interactive]
|
10
|
+
username = ask("Enter username: ") if username.blank?
|
11
|
+
if password.blank?
|
12
|
+
password = ask("Enter password: ") { |q| q.echo = "*" }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if username.blank? || password.blank?
|
17
|
+
err("Please enter username and password")
|
18
|
+
end
|
19
|
+
|
20
|
+
if director.create_user(username, password)
|
21
|
+
say("User #{username} has been created")
|
22
|
+
else
|
23
|
+
say("Error creating user")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli::Command
|
4
|
+
class Vms < Base
|
5
|
+
include Bosh::Cli::DeploymentHelper
|
6
|
+
|
7
|
+
def list(*args)
|
8
|
+
auth_required
|
9
|
+
|
10
|
+
show_full_stats = !args.delete("--full").nil?
|
11
|
+
name = args.first
|
12
|
+
|
13
|
+
if name.nil?
|
14
|
+
deployment_required
|
15
|
+
manifest = prepare_deployment_manifest
|
16
|
+
name = manifest["name"]
|
17
|
+
end
|
18
|
+
|
19
|
+
say("Deployment `#{name.green}'")
|
20
|
+
|
21
|
+
vms = director.fetch_vm_state(name)
|
22
|
+
err("No VMs") if vms.size == 0
|
23
|
+
|
24
|
+
sorted = vms.sort do |a, b|
|
25
|
+
s = a["job_name"].to_s <=> b["job_name"].to_s
|
26
|
+
s = a["index"].to_i <=> b["index"].to_i if s == 0
|
27
|
+
s = a["resource_pool"].to_s <=> b["resource_pool"].to_s if s == 0
|
28
|
+
s
|
29
|
+
end
|
30
|
+
|
31
|
+
vms_table = table do |t|
|
32
|
+
headings = ["Job/index", "State", "Resource Pool", "IPs"]
|
33
|
+
headings += ["Agent ID", "CID"] if show_full_stats
|
34
|
+
|
35
|
+
t.headings = headings
|
36
|
+
|
37
|
+
sorted.each do |vm|
|
38
|
+
job = "#{vm["job_name"]}/#{vm["index"]}" if vm["job_name"]
|
39
|
+
row = [job, vm["job_state"],
|
40
|
+
vm["resource_pool"], Array(vm["ips"]).join(", ")]
|
41
|
+
row += [vm["vm_cid"], vm["agent_id"]] if show_full_stats
|
42
|
+
t << row
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
say("\n")
|
47
|
+
say(vms_table)
|
48
|
+
say("\n")
|
49
|
+
say("VMs total: %d" % vms.size)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/lib/cli/config.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# Copyright (c) 2009-2012 VMware, Inc.
|
2
|
+
|
3
|
+
module Bosh::Cli
|
4
|
+
class Config
|
5
|
+
VALID_ID = /^[-a-z0-9_.]+$/i
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :colorize
|
9
|
+
attr_accessor :output
|
10
|
+
attr_accessor :interactive
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(filename, work_dir = Dir.pwd)
|
14
|
+
@filename = File.expand_path(filename)
|
15
|
+
@work_dir = work_dir
|
16
|
+
|
17
|
+
unless File.exists?(@filename)
|
18
|
+
File.open(@filename, "w") { |f| YAML.dump({}, f) }
|
19
|
+
File.chmod(0600, @filename)
|
20
|
+
end
|
21
|
+
|
22
|
+
@config_file = load_yaml_file(@filename, nil)
|
23
|
+
|
24
|
+
unless @config_file.is_a?(Hash)
|
25
|
+
@config_file = { } # Just ignore it if it's malformed
|
26
|
+
end
|
27
|
+
|
28
|
+
rescue SystemCallError => e
|
29
|
+
raise ConfigError, "Cannot read config file: #{e.message}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def auth
|
33
|
+
if @config_file.has_key?("auth") && @config_file["auth"].is_a?(Hash)
|
34
|
+
@config_file["auth"][target]
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_credentials(target, username, password)
|
41
|
+
@config_file["auth"] ||= { }
|
42
|
+
@config_file["auth"][target] = { "username" => username,
|
43
|
+
"password" => password }
|
44
|
+
end
|
45
|
+
|
46
|
+
def set_alias(category, alias_name, value)
|
47
|
+
@config_file["aliases"] ||= { }
|
48
|
+
@config_file["aliases"][category.to_s] ||= { }
|
49
|
+
@config_file["aliases"][category.to_s][alias_name] = value
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve_alias(category, alias_name)
|
53
|
+
category = category.to_s
|
54
|
+
|
55
|
+
if @config_file.has_key?("aliases") &&
|
56
|
+
@config_file["aliases"].is_a?(Hash) &&
|
57
|
+
@config_file["aliases"].has_key?(category) &&
|
58
|
+
@config_file["aliases"][category].is_a?(Hash) &&
|
59
|
+
!@config_file["aliases"][category][alias_name].blank?
|
60
|
+
@config_file["aliases"][category][alias_name].to_s
|
61
|
+
else
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def username
|
67
|
+
auth ? auth["username"] : nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def password
|
71
|
+
auth ? auth["password"] : nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# Deployment used to be a string that was only stored for your
|
75
|
+
# current target. As soon as you switched targets, the deployment
|
76
|
+
# was erased. If the user has the old config we convert it to the
|
77
|
+
# new config.
|
78
|
+
#
|
79
|
+
# @return [Boolean] Whether config is using the old deployment format.
|
80
|
+
def is_old_deployment_config?
|
81
|
+
@config_file["deployment"].is_a?(String)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Read the deployment configuration. Return the deployment for the
|
85
|
+
# current target.
|
86
|
+
#
|
87
|
+
# @return [String?] The deployment path for the current target.
|
88
|
+
def deployment
|
89
|
+
return nil if target.nil?
|
90
|
+
if @config_file.has_key?("deployment")
|
91
|
+
if is_old_deployment_config?
|
92
|
+
set_deployment(@config_file["deployment"])
|
93
|
+
save
|
94
|
+
end
|
95
|
+
if @config_file["deployment"].is_a?(Hash)
|
96
|
+
return @config_file["deployment"][target]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Sets the deployment file for the current target. If the deployment is
|
102
|
+
# the old deployment configuration, it will turn it into the format.
|
103
|
+
#
|
104
|
+
# @raise [MissingTarget] If there is no target set.
|
105
|
+
# @param [String] deployment_file_path The string path to the
|
106
|
+
# deployment file.
|
107
|
+
def set_deployment(deployment_file_path)
|
108
|
+
raise MissingTarget, "Must have a target set." if target.nil?
|
109
|
+
@config_file["deployment"] = { } if is_old_deployment_config?
|
110
|
+
@config_file["deployment"] ||= { }
|
111
|
+
@config_file["deployment"][target] = deployment_file_path
|
112
|
+
end
|
113
|
+
|
114
|
+
[:target, :target_name, :target_version, :release,
|
115
|
+
:target_uuid, :status_timeout].each do |attr|
|
116
|
+
define_method attr do
|
117
|
+
read(attr, false)
|
118
|
+
end
|
119
|
+
|
120
|
+
define_method "#{attr}=" do |value|
|
121
|
+
write_global(attr, value)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def read(attr, try_local_first = true)
|
126
|
+
attr = attr.to_s
|
127
|
+
if try_local_first && @config_file[@work_dir].is_a?(Hash) &&
|
128
|
+
@config_file[@work_dir].has_key?(attr)
|
129
|
+
@config_file[@work_dir][attr]
|
130
|
+
else
|
131
|
+
@config_file[attr]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def write(attr, value)
|
136
|
+
@config_file[@work_dir] ||= {}
|
137
|
+
@config_file[@work_dir][attr.to_s] = value
|
138
|
+
end
|
139
|
+
|
140
|
+
def write_global(attr, value)
|
141
|
+
@config_file[attr.to_s] = value
|
142
|
+
end
|
143
|
+
|
144
|
+
def save
|
145
|
+
File.open(@filename, "w") do |f|
|
146
|
+
YAML.dump(@config_file, f)
|
147
|
+
end
|
148
|
+
|
149
|
+
rescue SystemCallError => e
|
150
|
+
raise ConfigError, e.message
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|