cf 5.2.1.rc4 → 5.2.1.rc5
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.
- 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
|
+
|