cf 5.2.1.rc4 → 5.2.1.rc5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/admin/plugin.rb +1 -0
- data/lib/admin/service_broker/update.rb +52 -0
- data/lib/cf/cli.rb +8 -2
- data/lib/cf/cli/app/env.rb +41 -20
- data/lib/cf/cli/app/push.rb +10 -9
- data/lib/cf/cli/app/start.rb +13 -5
- data/lib/cf/cli/app/stats.rb +0 -1
- data/lib/cf/cli/start/target_prettifier.rb +22 -5
- data/lib/cf/version.rb +1 -1
- data/spec/admin/service_broker/update_spec.rb +43 -0
- data/spec/assets/hello-sinatra/manifest.yml +17 -0
- data/spec/cf/cli/app/env_spec.rb +261 -0
- data/spec/cf/cli/app/push_spec.rb +107 -63
- data/spec/cf/cli/app/start_spec.rb +12 -10
- data/spec/cf/cli_spec.rb +4 -17
- data/spec/features/push_flow_spec.rb +17 -1
- data/spec/features/service_brokers_spec.rb +14 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/cli_helper.rb +22 -0
- data/spec/support/mock_commands/mock_restart.rb +16 -0
- data/spec/support/mock_commands/mock_start.rb +17 -0
- metadata +14 -21
- data/spec/cf/object_extensions_spec.rb +0 -24
data/lib/admin/plugin.rb
CHANGED
@@ -0,0 +1,52 @@
|
|
1
|
+
require "cf/cli"
|
2
|
+
|
3
|
+
module CFAdmin::ServiceBroker
|
4
|
+
class Update < CF::CLI
|
5
|
+
def precondition
|
6
|
+
check_target
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Update a service broker"
|
10
|
+
group :admin
|
11
|
+
input :broker, :argument => :required,
|
12
|
+
:desc => "Service broker to update",
|
13
|
+
:from_given => by_name(:service_broker)
|
14
|
+
input :name, :argument => :optional,
|
15
|
+
:desc => "New name"
|
16
|
+
input :url,
|
17
|
+
:desc => "New URL"
|
18
|
+
input :token,
|
19
|
+
:desc => "New token"
|
20
|
+
|
21
|
+
def update_service_broker
|
22
|
+
broker = input[:broker]
|
23
|
+
|
24
|
+
old_name = broker.name
|
25
|
+
|
26
|
+
broker.name = input[:name]
|
27
|
+
finalize
|
28
|
+
broker.broker_url = input[:url]
|
29
|
+
finalize
|
30
|
+
broker.token = input[:token]
|
31
|
+
finalize
|
32
|
+
|
33
|
+
with_progress("Updating service broker #{old_name}") do
|
34
|
+
broker.update!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def ask_name
|
41
|
+
ask("Name")
|
42
|
+
end
|
43
|
+
|
44
|
+
def ask_url
|
45
|
+
ask("URL")
|
46
|
+
end
|
47
|
+
|
48
|
+
def ask_token
|
49
|
+
ask("Token")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/cf/cli.rb
CHANGED
@@ -158,12 +158,18 @@ EOS
|
|
158
158
|
formatted_exception_output(e, message)
|
159
159
|
|
160
160
|
rescue Exception => e
|
161
|
-
|
161
|
+
log_error_and_dump_crashlog(e)
|
162
|
+
end
|
163
|
+
|
164
|
+
def log_error_and_dump_crashlog(e)
|
165
|
+
log_error(e)
|
166
|
+
err File.open(File.expand_path(CF::CRASH_FILE)).readlines.join("")
|
167
|
+
|
168
|
+
raise if debug?
|
162
169
|
end
|
163
170
|
|
164
171
|
def formatted_exception_output(e, msg)
|
165
172
|
log_error(e)
|
166
|
-
msg << "\ncat #{CF::CRASH_FILE} # for more details"
|
167
173
|
err msg
|
168
174
|
|
169
175
|
raise if debug?
|
data/lib/cf/cli/app/env.rb
CHANGED
@@ -29,50 +29,71 @@ module CF::App
|
|
29
29
|
:argument => true, :from_given => by_name(:app)
|
30
30
|
input :name, :desc => "Variable name", :argument => true
|
31
31
|
input :value, :desc => "Variable value", :argument => :optional
|
32
|
-
input :restart, :desc => "Restart app after updating?", :default =>
|
32
|
+
input :restart, :desc => "Restart app after updating?", :default => false
|
33
|
+
|
33
34
|
def set_env
|
34
35
|
app = input[:app]
|
35
|
-
name =
|
36
|
-
|
37
|
-
if value = input[:value]
|
38
|
-
name = input[:name]
|
39
|
-
elsif name["="]
|
40
|
-
name, value = name.split("=")
|
41
|
-
end
|
42
|
-
|
43
|
-
unless name =~ VALID_ENV_VAR
|
44
|
-
fail "Invalid variable name; must match #{VALID_ENV_VAR.inspect}"
|
45
|
-
end
|
36
|
+
name, value = parse_name_and_value!
|
46
37
|
|
47
|
-
with_progress("Updating #{c(app.name, :name)}") do
|
38
|
+
with_progress("Updating env variable #{c(name, :name)} for app #{c(app.name, :name)}") do
|
48
39
|
app.env[name] = value
|
49
40
|
app.update!
|
50
41
|
end
|
51
42
|
|
52
|
-
|
53
|
-
invoke :restart, :app => app
|
54
|
-
end
|
43
|
+
restart_if_necessary(app)
|
55
44
|
end
|
56
45
|
|
57
|
-
|
58
46
|
desc "Remove an environment variable"
|
59
47
|
group :apps, :info
|
60
48
|
input :app, :desc => "Application to set the variable for",
|
61
49
|
:argument => true, :from_given => by_name(:app)
|
62
50
|
input :name, :desc => "Variable name", :argument => true
|
63
|
-
input :restart, :desc => "Restart app after updating?", :default =>
|
51
|
+
input :restart, :desc => "Restart app after updating?", :default => false
|
64
52
|
def unset_env
|
65
53
|
app = input[:app]
|
66
54
|
name = input[:name]
|
67
55
|
|
68
|
-
with_progress("
|
56
|
+
with_progress("Unsetting #{c(name, :name)} for app #{c(app.name, :name)}") do
|
69
57
|
app.env.delete(name)
|
70
58
|
app.update!
|
71
59
|
end
|
72
60
|
|
73
|
-
|
61
|
+
restart_if_necessary(app)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def restart_if_necessary(app)
|
67
|
+
unless input[:restart]
|
68
|
+
line c("TIP: Use 'cf push' to ensure your env variable changes take effect.", :warning)
|
69
|
+
return
|
70
|
+
end
|
71
|
+
|
72
|
+
if app.started?
|
74
73
|
invoke :restart, :app => app
|
74
|
+
else
|
75
|
+
line "Your app was unstarted. Starting now."
|
76
|
+
invoke :start, :app => app
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_name_and_value!
|
81
|
+
name = input[:name]
|
82
|
+
value = input[:value]
|
83
|
+
|
84
|
+
if name["="]
|
85
|
+
name, new_value, extra_values = name.split("=")
|
86
|
+
fail "You attempted to specify the value of #{name} twice." if value
|
87
|
+
fail "Invalid format: environment variable definition contains too many occurences of '='" if extra_values
|
88
|
+
value = new_value
|
89
|
+
end
|
90
|
+
|
91
|
+
unless name =~ VALID_ENV_VAR
|
92
|
+
fail "Invalid format: environment variable names cannot start with a number" if name[0] =~ /\d/
|
93
|
+
fail "Invalid format: environment variable names can only contain alphanumeric characters and underscores"
|
75
94
|
end
|
95
|
+
|
96
|
+
return name, value
|
76
97
|
end
|
77
98
|
end
|
78
99
|
end
|
data/lib/cf/cli/app/push.rb
CHANGED
@@ -49,15 +49,6 @@ module CF::App
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
def sync_app(app, path)
|
53
|
-
upload_app(app, path)
|
54
|
-
apply_changes(app)
|
55
|
-
display_changes(app)
|
56
|
-
commit_changes(app)
|
57
|
-
|
58
|
-
warn "\n#{c(app.name, :name)} is currently stopped, start it with 'cf start'" unless app.started?
|
59
|
-
end
|
60
|
-
|
61
52
|
def setup_new_app(path)
|
62
53
|
self.path = path
|
63
54
|
app = create_app(get_inputs)
|
@@ -70,6 +61,16 @@ module CF::App
|
|
70
61
|
|
71
62
|
private
|
72
63
|
|
64
|
+
def sync_app(app, path)
|
65
|
+
upload_app(app, path)
|
66
|
+
apply_changes(app)
|
67
|
+
input[:path]
|
68
|
+
display_changes(app)
|
69
|
+
commit_changes(app)
|
70
|
+
|
71
|
+
warn "\n#{c(app.name, :name)} is currently stopped, start it with 'cf start'" unless app.started?
|
72
|
+
end
|
73
|
+
|
73
74
|
def url_choices(name)
|
74
75
|
client.current_space.domains.sort_by(&:name).collect do |d|
|
75
76
|
# TODO: check availability
|
data/lib/cf/cli/app/start.rb
CHANGED
@@ -100,6 +100,7 @@ module CF::App
|
|
100
100
|
while true
|
101
101
|
if any_instance_flapping?(instances) || seconds == APP_CHECK_LIMIT
|
102
102
|
err "Push unsuccessful."
|
103
|
+
line "#{c("TIP: The system will continue to attempt restarting all requested app instances that have crashed. Try 'cf app' to monitor app status. To troubleshoot crashes, try 'cf events' and 'cf crashlogs'.", :warning)}"
|
103
104
|
return
|
104
105
|
end
|
105
106
|
|
@@ -108,8 +109,9 @@ module CF::App
|
|
108
109
|
|
109
110
|
indented { print_instances_summary(instances) }
|
110
111
|
|
111
|
-
if
|
112
|
+
if one_instance_running?(instances)
|
112
113
|
line "#{c("Push successful! App '#{app.name}' available at http://#{app.host}.#{app.domain}", :good)}"
|
114
|
+
line "#{c("TIP: The system will continue to start all requested app instances. Try 'cf app' to monitor app status.", :warning)}"
|
113
115
|
return
|
114
116
|
end
|
115
117
|
rescue CFoundry::NotStaged
|
@@ -124,8 +126,8 @@ module CF::App
|
|
124
126
|
end
|
125
127
|
end
|
126
128
|
|
127
|
-
def
|
128
|
-
instances.
|
129
|
+
def one_instance_running?(instances)
|
130
|
+
instances.any? { |i| i.state == "RUNNING" }
|
129
131
|
end
|
130
132
|
|
131
133
|
def any_instance_flapping?(instances)
|
@@ -145,9 +147,9 @@ module CF::App
|
|
145
147
|
end
|
146
148
|
|
147
149
|
states = []
|
148
|
-
%w{RUNNING STARTING DOWN
|
150
|
+
%w{RUNNING STARTING FLAPPING DOWN}.each do |state|
|
149
151
|
if (num = counts[state]) > 0
|
150
|
-
states << "#{b(num)} #{c(state
|
152
|
+
states << "#{b(num)} #{c(for_output(state), state_color(state))}"
|
151
153
|
end
|
152
154
|
end
|
153
155
|
|
@@ -157,5 +159,11 @@ module CF::App
|
|
157
159
|
ratio = "#{running}#{d(" of ")}#{total} instances running"
|
158
160
|
line "#{ratio} (#{states.join(", ")})"
|
159
161
|
end
|
162
|
+
|
163
|
+
private
|
164
|
+
def for_output(state)
|
165
|
+
state = "CRASHING" if state == "FLAPPING"
|
166
|
+
state.downcase
|
167
|
+
end
|
160
168
|
end
|
161
169
|
end
|
data/lib/cf/cli/app/stats.rb
CHANGED
@@ -1,11 +1,28 @@
|
|
1
|
-
require 'active_support/core_ext/object/try'
|
2
|
-
|
3
1
|
class TargetPrettifier
|
4
2
|
def self.prettify(client, outputter)
|
3
|
+
|
4
|
+
target = nil
|
5
|
+
version = nil
|
6
|
+
current_user_email = nil
|
7
|
+
current_space_name = nil
|
8
|
+
current_org_name = nil
|
9
|
+
|
10
|
+
if client
|
11
|
+
target = client.target
|
12
|
+
version = client.version
|
13
|
+
current_user = client.current_user
|
14
|
+
current_space = client.current_space
|
15
|
+
current_org = client.current_organization
|
16
|
+
|
17
|
+
current_user_email = current_user.email if current_user
|
18
|
+
current_space_name = current_space.name if current_space
|
19
|
+
current_org_name = current_org.name if current_org
|
20
|
+
end
|
21
|
+
|
5
22
|
outputter.line("Target Information (where will apps be pushed):")
|
6
|
-
outputter.line(" CF instance: #{print_var(
|
7
|
-
outputter.line(" user: #{print_var(
|
8
|
-
outputter.line(" target app space: #{print_var(
|
23
|
+
outputter.line(" CF instance: #{print_var(target, outputter)} (API version: #{print_var(version, outputter)})")
|
24
|
+
outputter.line(" user: #{print_var(current_user_email, outputter)}")
|
25
|
+
outputter.line(" target app space: #{print_var(current_space_name, outputter)} (org: #{print_var(current_org_name, outputter)})")
|
9
26
|
end
|
10
27
|
|
11
28
|
def self.print_var(object_name, outputter)
|
data/lib/cf/version.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe CFAdmin::ServiceBroker::Update do
|
4
|
+
let(:fake_home_dir) { "#{SPEC_ROOT}/fixtures/fake_admin_dir" }
|
5
|
+
stub_home_dir_with { fake_home_dir }
|
6
|
+
|
7
|
+
let(:client) { build(:client) }
|
8
|
+
|
9
|
+
let(:service_broker) { CFoundry::V2::ServiceBroker.new(nil, client) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
CFAdmin::ServiceBroker::Update.client = client
|
13
|
+
client.stub(:service_broker_by_name).with('cf-mysql').and_return(service_broker)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "updates a service broker when arguments are provided on the command line" do
|
17
|
+
service_broker.stub(:update!)
|
18
|
+
|
19
|
+
cf %W[update-service-broker --broker cf-mysql --name cf-othersql --url http://other.cfapp.io --token secret2]
|
20
|
+
|
21
|
+
service_broker.name.should == 'cf-othersql'
|
22
|
+
service_broker.broker_url.should == 'http://other.cfapp.io'
|
23
|
+
service_broker.token.should == 'secret2'
|
24
|
+
|
25
|
+
service_broker.should have_received(:update!)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "updates a service broker when no change arguments are provided" do
|
29
|
+
service_broker.stub(:update!)
|
30
|
+
|
31
|
+
stub_ask("Name").and_return("cf-othersql")
|
32
|
+
stub_ask("URL").and_return("http://other.example.com")
|
33
|
+
stub_ask("Token").and_return("token2")
|
34
|
+
|
35
|
+
cf %W[update-service-broker cf-mysql]
|
36
|
+
|
37
|
+
service_broker.name.should == 'cf-othersql'
|
38
|
+
service_broker.broker_url.should == 'http://other.example.com'
|
39
|
+
service_broker.token.should == 'token2'
|
40
|
+
|
41
|
+
service_broker.should have_received(:update!)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
applications:
|
3
|
+
- name: hello-sinatra-1377212364_2782688
|
4
|
+
memory: 256M
|
5
|
+
instances: 1
|
6
|
+
host: hello-sinatra-subdomain-1377212364_2782688
|
7
|
+
domain: cfapps.io
|
8
|
+
path: .
|
9
|
+
services:
|
10
|
+
user-provided-1377212364_2782688:
|
11
|
+
label: user-provided
|
12
|
+
credentials:
|
13
|
+
username: abc123
|
14
|
+
password: sunshine
|
15
|
+
hostname: oracle.enterprise.com
|
16
|
+
port: 1234
|
17
|
+
name: myoracledb2
|
@@ -0,0 +1,261 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "cf/cli/app/env"
|
3
|
+
|
4
|
+
module CF
|
5
|
+
module App
|
6
|
+
describe Env do
|
7
|
+
before do
|
8
|
+
stub_client
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#set_env' do
|
12
|
+
let(:mock_restart_command) { MockRestartCommand.new }
|
13
|
+
let(:mock_start_command) { MockStartCommand.new }
|
14
|
+
let(:client) { build(:client) }
|
15
|
+
let(:app) { build(:app, client: client, name: 'puppies-r-us-website') }
|
16
|
+
let(:env) { Env.new(Mothership.commands[:set_env]) }
|
17
|
+
|
18
|
+
before do
|
19
|
+
client.stub(:app_by_name).and_return(app)
|
20
|
+
env.input = Mothership::Inputs.new(Mothership.commands[:set_env], env, inputs, {}, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when name and value are specified' do
|
24
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', value: 'oh_what_a_value'} }
|
25
|
+
|
26
|
+
it 'updates the app with the new environment variable' do
|
27
|
+
expect(app.env['MY_LOVELY_SETTING']).to eq(nil)
|
28
|
+
expect(app).to receive(:update!) do
|
29
|
+
expect(app.env['MY_LOVELY_SETTING']).to eq('oh_what_a_value')
|
30
|
+
end
|
31
|
+
|
32
|
+
capture_output { env.set_env }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the environment variable is specified with the 'VAR=VALUE' format" do
|
37
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING=oh_what_a_value'} }
|
38
|
+
|
39
|
+
it 'updates the app with the new environment variable' do
|
40
|
+
expect(app.env['MY_LOVELY_SETTING']).to eq(nil)
|
41
|
+
expect(app).to receive(:update!) do
|
42
|
+
expect(app.env['MY_LOVELY_SETTING']).to eq('oh_what_a_value')
|
43
|
+
end
|
44
|
+
|
45
|
+
capture_output { env.set_env }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "environment variable format" do
|
50
|
+
context "when the name has only letters, numbers, and underscores" do
|
51
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING123', value: "oh_what_a_value"} }
|
52
|
+
it "gets the value from the input[:value]" do
|
53
|
+
expect(app.env['MY_LOVELY_SETTING123']).to eq(nil)
|
54
|
+
app.stub(:update!)
|
55
|
+
|
56
|
+
capture_output { env.set_env }
|
57
|
+
expect(app.env['MY_LOVELY_SETTING123']).to eq("oh_what_a_value")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when the name has one equal sign, and is otherwise valid" do
|
62
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING123=oh_what_a_value'} }
|
63
|
+
it "gets the value by parsing the name" do
|
64
|
+
expect(app.env['MY_LOVELY_SETTING123']).to eq(nil)
|
65
|
+
app.stub(:update!)
|
66
|
+
|
67
|
+
capture_output { env.set_env }
|
68
|
+
expect(app.env['MY_LOVELY_SETTING123']).to eq("oh_what_a_value")
|
69
|
+
end
|
70
|
+
|
71
|
+
context "but provides a value anyway" do
|
72
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING123=oh_what_a_value', value: 'my_other_value'} }
|
73
|
+
|
74
|
+
it "gives the user an error" do
|
75
|
+
capture_exceptional_output { env.set_env }
|
76
|
+
expect(error_output).to say "You attempted to specify the value of MY_LOVELY_SETTING123 twice."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when the name has more than one equal sign" do
|
82
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING123=oh_what_a_value=badbadbad'} }
|
83
|
+
it "gives the user an error" do
|
84
|
+
capture_exceptional_output { env.set_env }
|
85
|
+
expect(error_output).to say "Invalid format: environment variable definition contains too many occurences of '='"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when there are characters that are not letters, numbers, or underscores" do
|
90
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING1?#$=value'} }
|
91
|
+
it "raises an error" do
|
92
|
+
capture_exceptional_output { env.set_env }
|
93
|
+
expect(error_output).to say "Invalid format: environment variable names can only contain alphanumeric characters and underscores"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "when the name starts with a number" do
|
98
|
+
let(:inputs) { {app: app, name: '1MY_LOVELY_SETTING', value: 'oh_what_a_value'} }
|
99
|
+
it "raises an error" do
|
100
|
+
capture_exceptional_output { env.set_env }
|
101
|
+
expect(error_output).to say "Invalid format: environment variable names cannot start with a number"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when the app is not started' do
|
107
|
+
context 'with the --restart flag' do
|
108
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', value: 'oh_what_a_value', restart: true} }
|
109
|
+
before { Start.stub(:new).and_return(mock_start_command) }
|
110
|
+
|
111
|
+
it 'starts the app' do
|
112
|
+
expect(app).to receive(:update!) do
|
113
|
+
expect(mock_start_command.started_apps).to be_empty
|
114
|
+
end
|
115
|
+
|
116
|
+
capture_output { env.set_env }
|
117
|
+
expect(output).to say "Your app was unstarted. Starting now."
|
118
|
+
|
119
|
+
expect(mock_start_command.started_apps).to eq [app]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'without the --restart flag' do
|
124
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', value: 'oh_what_a_value', restart: false} }
|
125
|
+
|
126
|
+
before do
|
127
|
+
app.stub(:update!)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "suggests a 'cf push' to the user" do
|
131
|
+
capture_output { env.set_env }
|
132
|
+
expect(output).to say "TIP: Use 'cf push' to ensure your env variable changes take effect."
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'when the app is already started' do
|
138
|
+
before do
|
139
|
+
app.stub(:started?) { true }
|
140
|
+
Restart.stub(:new).and_return(mock_restart_command)
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'with the --restart flag' do
|
144
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', value: 'oh_what_a_value', restart: true} }
|
145
|
+
|
146
|
+
it 'restarts the app' do
|
147
|
+
expect(app).to receive(:update!) do
|
148
|
+
expect(mock_restart_command.restarted_apps).to be_empty
|
149
|
+
end
|
150
|
+
|
151
|
+
capture_output { env.set_env }
|
152
|
+
|
153
|
+
expect(mock_restart_command.restarted_apps).to eq([app])
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'without the --restart flag' do
|
158
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', value: 'oh_what_a_value', restart: false} }
|
159
|
+
before do
|
160
|
+
app.stub(:update!)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'does not restart the app but suggests a cf push' do
|
164
|
+
capture_output { env.set_env }
|
165
|
+
expect(mock_restart_command.restarted_apps).to be_empty
|
166
|
+
expect(output).to say "TIP: Use 'cf push' to ensure your env variable changes take effect."
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#unset_env' do
|
173
|
+
let(:app) { build(:app, client: client, name: 'puppies-r-us-website', environment_json: {'MY_LOVELY_SETTING' => 'oh_so_lovely'}) }
|
174
|
+
let(:client) { build(:client) }
|
175
|
+
let(:env) { Env.new(Mothership.commands[:unset_env]) }
|
176
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING'} }
|
177
|
+
let(:mock_start_command) { MockStartCommand.new }
|
178
|
+
let(:mock_restart_command) { MockRestartCommand.new }
|
179
|
+
|
180
|
+
before do
|
181
|
+
env.input = Mothership::Inputs.new(Mothership.commands[:unset_env], env, inputs, {}, {})
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'unsets the environment variable and updates the app' do
|
185
|
+
expect(app.env['MY_LOVELY_SETTING']).to eq('oh_so_lovely')
|
186
|
+
expect(app).to receive(:update!) do
|
187
|
+
expect(app.env['MY_LOVELY_SETTING']).to be_nil
|
188
|
+
end
|
189
|
+
|
190
|
+
capture_output { env.unset_env }
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when the app is not started' do
|
194
|
+
context 'with the --restart flag' do
|
195
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', restart: true} }
|
196
|
+
before { Start.stub(:new).and_return(mock_start_command) }
|
197
|
+
|
198
|
+
it 'starts the app' do
|
199
|
+
expect(app).to receive(:update!) do
|
200
|
+
expect(mock_start_command.started_apps).to be_empty
|
201
|
+
end
|
202
|
+
|
203
|
+
capture_output { env.unset_env }
|
204
|
+
expect(output).to say "Your app was unstarted. Starting now."
|
205
|
+
|
206
|
+
expect(mock_start_command.started_apps).to eq [app]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'without the --restart flag' do
|
211
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING'} }
|
212
|
+
|
213
|
+
before do
|
214
|
+
app.stub(:update!)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "suggests a 'cf push' to the user" do
|
218
|
+
capture_output { env.unset_env }
|
219
|
+
expect(output).to say "TIP: Use 'cf push' to ensure your env variable changes take effect."
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'when the app is already started' do
|
225
|
+
before do
|
226
|
+
app.stub(:started?) { true }
|
227
|
+
Restart.stub(:new).and_return(mock_restart_command)
|
228
|
+
end
|
229
|
+
|
230
|
+
context 'with the --restart flag' do
|
231
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', restart: true} }
|
232
|
+
|
233
|
+
it 'restarts the app' do
|
234
|
+
expect(app).to receive(:update!) do
|
235
|
+
expect(mock_restart_command.restarted_apps).to be_empty
|
236
|
+
end
|
237
|
+
|
238
|
+
capture_output { env.unset_env }
|
239
|
+
|
240
|
+
expect(mock_restart_command.restarted_apps).to eq([app])
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'without the --restart flag' do
|
245
|
+
let(:inputs) { {app: app, name: 'MY_LOVELY_SETTING', restart: false} }
|
246
|
+
before do
|
247
|
+
app.stub(:update!)
|
248
|
+
end
|
249
|
+
|
250
|
+
it 'does not restart the app but suggests a cf push' do
|
251
|
+
capture_output { env.unset_env }
|
252
|
+
expect(mock_restart_command.restarted_apps).to be_empty
|
253
|
+
expect(output).to say "TIP: Use 'cf push' to ensure your env variable changes take effect."
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|