Flucti-flucti-cli 0.1.16

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 (65) hide show
  1. data/LICENSE +7 -0
  2. data/README.mdown +24 -0
  3. data/Rakefile +56 -0
  4. data/TODO.txt +19 -0
  5. data/bin/flucti +4 -0
  6. data/flucti-cli.gemspec +46 -0
  7. data/lib/flucti.rb +20 -0
  8. data/lib/flucti/api_access.rb +56 -0
  9. data/lib/flucti/cli.rb +107 -0
  10. data/lib/flucti/parameters.rb +37 -0
  11. data/lib/flucti/resources.rb +41 -0
  12. data/lib/flucti/resources/account.rb +7 -0
  13. data/lib/flucti/resources/app_type.rb +18 -0
  14. data/lib/flucti/resources/backend.rb +28 -0
  15. data/lib/flucti/resources/basic_resource.rb +16 -0
  16. data/lib/flucti/resources/container.rb +15 -0
  17. data/lib/flucti/resources/db_server.rb +38 -0
  18. data/lib/flucti/resources/domain.rb +8 -0
  19. data/lib/flucti/resources/general.rb +14 -0
  20. data/lib/flucti/resources/mail_client.rb +7 -0
  21. data/lib/flucti/resources/mail_server.rb +7 -0
  22. data/lib/flucti/resources/port_forwarding.rb +15 -0
  23. data/lib/flucti/resources/port_forwarding/services +13921 -0
  24. data/lib/flucti/resources/ssh_details.rb +96 -0
  25. data/lib/flucti/resources/webserver.rb +9 -0
  26. data/lib/flucti/resources/website.rb +9 -0
  27. data/lib/flucti/tasks.rb +3 -0
  28. data/lib/flucti/tasks/apikey_tasks.rb +57 -0
  29. data/lib/flucti/tasks/apptype_tasks.rb +264 -0
  30. data/lib/flucti/tasks/connect_pack.rb +161 -0
  31. data/lib/flucti/tasks/db_tasks.rb +158 -0
  32. data/lib/flucti/tasks/mail_tasks.rb +104 -0
  33. data/lib/flucti/tasks/miscellaneous_tasks.rb +6 -0
  34. data/lib/flucti/tasks/progress_tasks.rb +24 -0
  35. data/lib/flucti/tasks/sshkey_tasks.rb +151 -0
  36. data/lib/flucti/tasks/vps/firewall_tasks.rb +84 -0
  37. data/lib/flucti/tasks/vps_tasks.rb +37 -0
  38. data/lib/flucti/tasks/webserver_tasks.rb +154 -0
  39. data/lib/flucti/tasks/website/apptype_tasks.rb +42 -0
  40. data/lib/flucti/tasks/website/backends/instances_tasks.rb +37 -0
  41. data/lib/flucti/tasks/website/backends_tasks.rb +254 -0
  42. data/lib/flucti/tasks/website/capfile_tasks.rb +41 -0
  43. data/lib/flucti/tasks/website/domains_tasks.rb +107 -0
  44. data/lib/flucti/tasks/website_tasks.rb +221 -0
  45. data/lib/flucti/utilities.rb +20 -0
  46. data/lib/flucti/utilities/connection_error_handling.rb +50 -0
  47. data/lib/flucti/utilities/core_ext.rb +35 -0
  48. data/lib/flucti/utilities/list_displayer.rb +57 -0
  49. data/lib/flucti/utilities/miscellaneous.rb +65 -0
  50. data/lib/flucti/utilities/progress_bar.rb +17 -0
  51. data/lib/flucti/utilities/table.rb +25 -0
  52. data/lib/flucti/utilities/task_packing.rb +10 -0
  53. data/lib/flucti/utilities/user_interface.rb +117 -0
  54. data/lib/vendor/ruby-progressbar-0.9/lib/ChangeLog +113 -0
  55. data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.en.rd +103 -0
  56. data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.ja.rd +100 -0
  57. data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.rb +236 -0
  58. data/lib/vendor/ruby-progressbar-0.9/lib/test.rb +105 -0
  59. data/test/flucti/resources_test.rb +32 -0
  60. data/test/flucti/tasks_test.rb +28 -0
  61. data/test/flucti/utilities/miscellaneous_test.rb +54 -0
  62. data/test/flucti/utilities/table_test.rb +28 -0
  63. data/test/flucti/utilities/user_interface_test.rb +161 -0
  64. data/test/test_helper.rb +5 -0
  65. metadata +221 -0
@@ -0,0 +1,84 @@
1
+ namespace :vps do
2
+ namespace :firewall do
3
+ # Allow for defining task named `open':
4
+ class << self
5
+ undef_method :open if private_method_defined? :open
6
+ end
7
+
8
+ task(:default) { rules }
9
+
10
+ desc <<-DESC
11
+ Open a port from the Internet to a VPS. For example, if you choose to
12
+ open port 443 of a VPS foo, it will be accessible from the Internet on a
13
+ port greater than or equal to 1025, like 1047. As a result, packets
14
+ would arrive like this:
15
+
16
+ Internet <=> (Firewall:1047) <=> VPS:443
17
+
18
+ Following on this example:
19
+ $ #{command 'vps:firewall:open'} PORT=443
20
+
21
+ As 443 is the default HTTP SSL port number, you can a host site over SSL
22
+ and it will be accessible from the Internet on port 1047, for example at
23
+ https://www.example.com:1047.
24
+
25
+ By default, a port is open from the Internet. But you can restrict the
26
+ access to only one or several of your VPS's by specifying the $FROM
27
+ variable.
28
+
29
+ For example, to open port 3306 (MySQL) of VPS #{q 'trever'} to another
30
+ VPS #{q 'christina'}:
31
+ $ #{command 'vps:firewall:open'} FROM=christina ID=trever PORT=3306
32
+
33
+ Environment variables:
34
+ (mandatory) $PORT: the destination port number on the VPS, in the form
35
+ of <port>[:<protocol>], where <protocol> is optional
36
+ and is one of TCP or UDP, TCP being the default if
37
+ none is specified. For example:
38
+ $ #{command 'vps:firewall:open'} PORT=443
39
+ Is equivalent to:
40
+ $ #{command 'vps:firewall:open'} PORT=443:TCP
41
+
42
+ (optional) $FROM: the origin to grant access to. It can be either a
43
+ VPS identified by its hostname, or the Internet,
44
+ identified by #{q 'internet'}. Valid values
45
+ include:
46
+ FROM=internet # default
47
+ Or:
48
+ FROM=foo # VPS whose hostname is `foo'
49
+
50
+ (optional) $ID: the ID or hostname of the destination VPS.
51
+ Default: the newest VPS.
52
+ DESC
53
+ task :open do
54
+ vps = top.vps.fetch_current
55
+ port = ENV["PORT"] or error! <<-MSG
56
+ The destination port must be specified in the $PORT environment
57
+ variable, in the form of <port>[:<protocol>].
58
+ Examples: PORT=443, PORT=443:TCP, PORT=53:UDP
59
+ MSG
60
+ sources = (ENV['FROM'] || 'internet').split(',')
61
+ number, protocol = port.to_s.split(':')
62
+ protocol ||= 'TCP'
63
+ fwd = vps.port_forwardings.build :sources => sources, :to => number, :protocol => protocol
64
+ try_save fwd do
65
+ puts_title "Request sent"
66
+ puts "#{fwd.protocol.to_s.upcase} port #{fwd.to} has been scheduled for opening on VPS #{vps}."
67
+ end
68
+ end
69
+
70
+ desc <<-DESC
71
+ List all firewall rules defined for a given VPS.
72
+ DESC
73
+ task :rules do
74
+ vps = top.vps.fetch_current
75
+
76
+ puts_title "Firewall rules for VPS #{q vps}"
77
+ puts_list vps.port_forwardings.all, :table => true do |t|
78
+ t.col("Service") { |f| f.service_name || "(#{f.protocol})" }
79
+ t.col("Sources") { |f| "{#{f.simplified_sources * ', '}}:#{f.from}" }
80
+ t.col("Destination") { |f| "#{f.target}:#{f.to}" }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,37 @@
1
+ namespace :vps do
2
+ task(:default) { list }
3
+ import_pack(:connect, self, "VPS")
4
+
5
+ desc <<-DESC
6
+ Display a list of all your VPS's.
7
+ DESC
8
+ task :list do
9
+ puts_title "All VPS's"
10
+ puts_list VPS.all do |t|
11
+ t.col("Hostname", :hostname)
12
+ t.col("Memory capacity") { |s| "#{s.memory_capacity} MB" }
13
+ t.col("Disk capacity") { |s| "#{s.disk_capacity} GB" }
14
+ t.col("Status") { |s| s.status.to_s.capitalize }
15
+ end
16
+ end
17
+
18
+ desc <<-DESC
19
+ Display a list of hostsnames of all your VPS's. Useful for refering to
20
+ these programmatically.
21
+ DESC
22
+ task :hostnames do
23
+ VPS.all.each { |vps| puts vps.hostname }
24
+ end
25
+
26
+ desc <<-DESC
27
+ List all users (UNIX accounts) that have a home folder.
28
+ DESC
29
+ task :users do
30
+ ENV['CMD'] = "ls /home | grep -v ^_"
31
+ run
32
+ end
33
+
34
+ def fetch_current
35
+ (id = ENV["ID"] || ENV["ON"]) ? VPS.find(id) : VPS.last
36
+ end
37
+ end
@@ -0,0 +1,154 @@
1
+ namespace :webserver do
2
+ task(:default) { list }
3
+ import_pack(:connect, self, "webserver")
4
+
5
+ desc <<-DESC
6
+ List all webservers on either a particular VPS, or all VPS's.
7
+
8
+ Environment variables:
9
+ (optional) $ON: hostname of the VPS to list the webservers of.
10
+ Default: the newest VPS.
11
+ DESC
12
+ task :list do
13
+ puts_title "All webservers"
14
+ puts_list particular_set_of_webservers || Webserver.all, :title => :vps do |t|
15
+ t.col("Running on", :vps)
16
+ t.col("Running as", :user)
17
+ end
18
+ end
19
+
20
+ desc <<-DESC
21
+ Make sure that at least one webserver is present. Failing that, one is set
22
+ up automatically on the newest VPS.
23
+ DESC
24
+ task :ensure_any do
25
+ if (count = Webserver.all.size).zero?
26
+ setup
27
+ else
28
+ puts_title "Webserver present"
29
+ puts "There exists #{count} webservers."
30
+ end
31
+ end
32
+
33
+ desc <<-DESC
34
+ Set up a new webserver on a given VPS. Automatically installs and
35
+ configures the necessary software, running as its own UNIX user for
36
+ security purposes.
37
+
38
+ Environment variables:
39
+ (optional) $ON: hostname of the VPS to set up the webserver onto.
40
+ Default: the newest VPS.
41
+ DESC
42
+ task :setup do
43
+ vps = particular_vps || VPS.last
44
+ webserver = vps.webservers.build
45
+
46
+ try_save webserver do
47
+ puts_title "Request sent"
48
+ puts "Webserver successfully scheduled for setup on VPS #{q vps}."
49
+ end
50
+ end
51
+
52
+ desc <<-DESC
53
+ Force the setup procedure of a webserver to be re-run. You might want to
54
+ do that if you think you messed up the automatic configuration, UNIX
55
+ account or software installations.
56
+
57
+ Environment variables:
58
+ (optional) $ID: the ID of the webserver (get the list with #{qcommand "webserver:list"}).
59
+ Default: the webserver last set up.
60
+ DESC
61
+ task :reprepare do
62
+ fetch_current.put(:reprepare)
63
+ puts_title "Request sent"
64
+ puts "Webserver has been scheduled for re-preparation."
65
+ end
66
+
67
+ desc <<-DESC
68
+ Force the reconfiguration of a webserver. You might want to do that if you
69
+ think you messed up the automatic configuration.
70
+
71
+ Environment variables:
72
+ (optional) $ID: the ID of the webserver (get the list with #{qcommand "webserver:list"}).
73
+ Default: the webserver last set up.
74
+ DESC
75
+ task :reconfigure do
76
+ fetch_current.put(:reconfigure)
77
+ puts_title "Request sent"
78
+ puts "Webserver has been scheduled for re-configuration."
79
+ end
80
+
81
+ desc <<-DESC
82
+ List all websites hosted by a given webserver. That is, websites served
83
+ via the webserver by having one of their backends running on the same VPS
84
+ as the webserver.
85
+
86
+ Environment variables:
87
+ $ID: the ID of the webserver (get the list with #{qcommand "webserver:list"}).
88
+ DESC
89
+ task :hosted do
90
+ webserver = fetch_current!
91
+
92
+ puts_title "Hosted websites"
93
+ top.website.backends.show_list(webserver.backends.all)
94
+ end
95
+
96
+ desc <<-DESC
97
+ Remove a webserver. This is accomplished by stopping all services run as
98
+ the UNIX user of the webserver, and then suppressing that user.
99
+
100
+ No data is lost: as with any automated suppression of a UNIX user, the
101
+ home folder is backed up at /home/_foo, where "foo" is the name newly
102
+ suppressed user.
103
+
104
+ The removal of a webserver is only allowed once all the backends of the
105
+ sites it serves have been removed (or switched webservers by way of
106
+ removal followed by re-creation). Get the list of all these remaining
107
+ backends with #{qcommand "webserver:hosted"}.
108
+
109
+ Environment variables:
110
+ $ID: the ID of the webserver (get the list with #{qcommand "webserver:list"}).
111
+ DESC
112
+ task :remove do
113
+ webserver = fetch_current!
114
+
115
+ begin
116
+ webserver.destroy
117
+ rescue WebService::ResourceConflict
118
+ error! $!.response.data['errors']
119
+ else
120
+ puts_title "Request sent"
121
+ puts "Webserver on VPS #{q webserver.vps} has been scheduled for removal."
122
+ end
123
+ end
124
+
125
+ def require_id!
126
+ ENV["ID"] or
127
+ error! <<-MSG
128
+ The ID of the webserver to deal with must be specified by setting the
129
+ $ID environment variable. To list all webservers, run
130
+ #{qcommand "webserver:list"}.
131
+ MSG
132
+ end
133
+
134
+ def fetch_current
135
+ particular_webserver || Webserver.last
136
+ end
137
+
138
+ def fetch_current!
139
+ id = require_id!
140
+ Webserver.find(id)
141
+ end
142
+
143
+ def particular_vps
144
+ VPS.find(ENV["ON"]) if ENV["ON"]
145
+ end
146
+
147
+ def particular_webserver
148
+ Webserver.find(ENV["ID"]) if ENV["ID"]
149
+ end
150
+
151
+ def particular_set_of_webservers
152
+ vps = particular_vps and vps.webservers
153
+ end
154
+ end
@@ -0,0 +1,42 @@
1
+ namespace :website do
2
+ namespace :apptype do
3
+ desc <<-DESC
4
+ Change the application type of the website in the current working
5
+ directory.
6
+
7
+ When declaring a website, a type is (automatically or explicitely)
8
+ assigned to it. It is possible to change that initial choice with this
9
+ task:
10
+ $ cd path/to/foo
11
+ $ #{command "website:apptype:switch"} ID=custom
12
+ $ #{command "website:backends:reprepare"}
13
+
14
+ Environment variables:
15
+ $ID: the ID or short name of the application type to switch to.
16
+ DESC
17
+ task :switch do
18
+ website, type_id = fetch_current!, require_id!
19
+
20
+ website.app_type = AppType.find(type_id)
21
+
22
+ try_save website do
23
+ puts_title "Application type switched"
24
+ puts_long <<-MSG
25
+ * The application type of website #{q website} has been successfully
26
+ switched to #{q website.app_type}.
27
+
28
+ * Remember to re-reprepare all backends with
29
+ #{qcommand "website:backends:reprepare"}.
30
+ MSG
31
+ end
32
+ end
33
+
34
+ def require_id!
35
+ ENV["ID"] || ENV["TO"] or
36
+ error! <<-MSG
37
+ The ID or short name of the application type to switch to must be
38
+ specified by setting the $ID environment variable.
39
+ MSG
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ namespace :website do
2
+ namespace :backends do
3
+ namespace :instances do
4
+ environment_variables = <<-EOS
5
+ Environment variables:
6
+ (optional) $ID: the ID of the backend to alter.
7
+ Default: the backend last added.
8
+ EOS
9
+
10
+ desc <<-DESC
11
+ Bump up the number of instances a backend. This adds one more process to
12
+ the backend, allowing for processing more requests per second, but also
13
+ consuming more memory.
14
+
15
+ The default is 1. This tasks increments the current number by 1.
16
+
17
+ #{environment_variables}
18
+ DESC
19
+ task :more do
20
+ backend = backends.fetch_current
21
+ backend.post(:instances)
22
+ puts "Number of instances of backend #{backend} scheduled for increase."
23
+ end
24
+
25
+ desc <<-DESC
26
+ Decrease the number of instances of a backend.
27
+
28
+ #{environment_variables}
29
+ DESC
30
+ task :less do
31
+ backend = backends.fetch_current
32
+ backend.delete(:instances)
33
+ puts "Number of instances of backend #{backend} scheduled for decrease."
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,254 @@
1
+ namespace :website do
2
+ namespace :backends do
3
+ # Allow for defining tasks named `test' and `try':
4
+ class << self
5
+ undef_method :test if private_method_defined? :test
6
+ undef_method :try if public_method_defined? :try
7
+ end
8
+
9
+ task(:default) { list }
10
+ import_pack(:connect, self, "backend")
11
+
12
+ desc <<-DESC
13
+ List all the backends currently running the site.
14
+ DESC
15
+ task :list do
16
+ site = website.fetch_current!
17
+
18
+ puts_title "Backends of website: #{site}"
19
+ show_list(site.backends.all)
20
+ end
21
+
22
+ desc <<-DESC
23
+ Prepare a VPS for hosting the current website. So is done by creating a
24
+ dedicated UNIX user to run the site as, enclosing processes related to
25
+ the site in a tight, secure environment. This prevents potential
26
+ security flaws to have an impact on other services run within the same
27
+ VPS.
28
+
29
+ Environment variables:
30
+ (optional) $ON: hostname of the VPS. Default: last webserver set up.
31
+ (optional) $AS: UNIX account to run the services as. Default: the
32
+ name of the website.
33
+ DESC
34
+ task :add do
35
+ site = website.fetch_current!
36
+
37
+ unless webserver = (ENV["ON"] ? (vps = VPS.find(ENV["ON"])).webservers : Webserver).last
38
+ message = vps ? "No webserver seems to be running on VPS #{q vps}." : "You have no webserver set up yet."
39
+ message << " Set one up first by running #{qcommand "webserver:setup"}."
40
+ error! message
41
+ end
42
+
43
+ # Backend: ties together the site to the webserver
44
+ backend = site.backends.build(:webserver => webserver, :user => ENV["AS"])
45
+
46
+ try_save backend do
47
+ puts_title "Request sent"
48
+ puts_long <<-INFO
49
+ * A new backend for website #{q site} has been scheduled for setup
50
+ on VPS #{q backend.vps}.
51
+
52
+ * If you are using an automatically generated Capfile, you should
53
+ download an updated version with #{qcommand "website:capfile:download"}.
54
+
55
+ * Once the new backend is ready (check that #{qcommand "progress"}
56
+ is at 100%), you should re-deploy to push the site to it. If you
57
+ are using a Capfile, this is done with #{q "cap deploy:setup"}
58
+ followed by #{q "cap deploy"}.
59
+ INFO
60
+ end
61
+ end
62
+
63
+ desc <<-DESC
64
+ Force a re-configuration of a backend. Checks the UNIX user,
65
+ re-generates configuration files and reloads the webserver's
66
+ configuration if necessary.
67
+
68
+ Environment variables:
69
+ (optional) $ID: the ID of a particular backend (get the list with
70
+ #{qcommand "website:backends:list"}).
71
+
72
+ Default: all backends of the current websites are
73
+ scheduled for reconfiguration.
74
+ DESC
75
+ task :reconfigure do
76
+ backends = fetch_several
77
+
78
+ puts_title "Sending requests"
79
+ backends.each do |backend|
80
+ backend.put(:reconfigure)
81
+ puts "Backend #{backend} has been scheduled for reconfiguration."
82
+ end
83
+ end
84
+
85
+ desc <<-DESC
86
+ Force a re-preparation of a backend.
87
+
88
+ This re-runs the whole preparation process that was performed at
89
+ addition time. It's necessary to perform the preparation again when
90
+ switching application types of a website. For example:
91
+ $ cd path/to/foo
92
+ $ #{command "website:apptype:switch"} ID=custom
93
+ $ #{command "website:backends:reprepare"}
94
+ DESC
95
+ task :reprepare do
96
+ backends = fetch_several
97
+
98
+ puts_title "Sending requests"
99
+ backends.each do |backend|
100
+ backend.put(:reprepare)
101
+ puts "Backend #{backend} has been scheduled for re-preparation."
102
+ end
103
+ end
104
+
105
+ task :test do
106
+ backend = fetch_current
107
+ execute = lambda { |command| top.webserver.connect.ssh_details_for(webserver).execute(command) }
108
+
109
+ # Check for errors during installations
110
+ puts_title "Installations"
111
+ none, display = true, lambda do |error, script_name|
112
+ begin
113
+ error = backend.send(error)
114
+ puts_subtitle "Error while executing #{q script_name}"
115
+ puts error.output
116
+ rescue WebService::ResourceNotFound
117
+ # ignore
118
+ else
119
+ none = false
120
+ end
121
+ end
122
+ display[:root_install_error, 'root_install.sh']
123
+ display[:install_error, 'install.sh']
124
+ puts "No error occured during installations." if none
125
+
126
+ # Check syntax of webserver configuration file
127
+ puts_title "Webserver configuration"
128
+ webserver = backend.webserver
129
+ command = "/usr/sbin/nginx -c $HOME/webserver/nginx_main.conf -t"
130
+ top.webserver.connect.ssh_details_for(webserver).execute(command)
131
+
132
+ # Fetch the home page locally
133
+ puts_title "Home page (beginning)"
134
+ command = "wget -q -O - localhost:#{backend.port} | head -15"
135
+ top.website.backends.connect.ssh_details_for(backend).execute(command)
136
+ end
137
+
138
+ desc <<-DESC
139
+ Detect errors on service startup. Try to run the service script
140
+ (*_start.sh of the app. type) like the service manager would, in order
141
+ to spot errors output during startup, that would otherwise land in an
142
+ error log. Eases the task of debugging why an application progress
143
+ won't start like when forgetting to install a necessary RubyGem.
144
+
145
+ Environment variables:
146
+ (optional) $ID: the ID of the backend to try to start the service within.
147
+ Default: the backend last added.
148
+ DESC
149
+ task :try do
150
+ backend = fetch_current
151
+
152
+ if type = backend.website.app_type
153
+ type.service_configs.each do |service|
154
+ run = lambda { |cmd| connect.ssh_details_for(backend).execute(cmd) }
155
+
156
+ # Display service status
157
+ dir = "$HOME/service/#{backend.website.name}-#{service.name}-1"
158
+ run["sv status #{dir}"]
159
+
160
+ # Try to start the service in the foreground to spot errors on startup
161
+ command = "#{dir}/run"
162
+ command = "p=$$; ((sleep 2; kill $p) &); #{command}" # timeout
163
+ run[command]
164
+ end
165
+ end
166
+ end
167
+
168
+ desc <<-DESC
169
+ Stop a backend and clear site-related files in a soft way.
170
+
171
+ All the files related to the associated website are not deleted, but
172
+ instead moved in a backup directory in the home folder of the backends's
173
+ UNIX account.
174
+
175
+ This UNIX account is then soft-cleared in a similar fashion. That is, it
176
+ is unregistered from the system, and its files are moved to a backup
177
+ directory under /home.
178
+
179
+ Example backup directory for a backend running as "foo":
180
+ /home/_foo
181
+
182
+ Example backup directory for a website named "bar" on this backend:
183
+ /home/_foo/_bar
184
+
185
+ That way, the VPS is kept in a clean state, and your files are still
186
+ available for you to get them back if you need them. This would most
187
+ likely be the case if the site accepts uploads stored on the filesystem,
188
+ in a subdirectory of the site's root, like RAILS_ROOT/public/images/ for
189
+ a Rails application, or wp-content/ for a WordPress blog.
190
+
191
+ Environment variables:
192
+ $ID: the ID of the backend to remove.
193
+ DESC
194
+ task :remove do
195
+ id = require_id!
196
+
197
+ website = top.website.fetch_current!
198
+ backend = website.backends.find(id)
199
+
200
+ if website.backends.all.size <= 1
201
+ confirm <<-WARN
202
+ You are about to remove the only backend left for this website. If
203
+ you do proceed with the removal, the site will become offline until
204
+ you set up a new one with #{qcommand "website:backends:add"} and
205
+ re-deploy.
206
+ WARN
207
+ end
208
+
209
+ backend.destroy
210
+
211
+ puts_title "Request sent"
212
+ puts_long <<-INFO
213
+ * Backend #{backend} has been scheduled for removal.
214
+
215
+ * If you are using the automatically generated Capfile, you should
216
+ download the updated version with #{qcommand "website:capfile:download"}.
217
+ INFO
218
+ end
219
+
220
+ def require_id!
221
+ ENV["ID"] or
222
+ error! <<-MSG
223
+ The ID of the backend to deal with must be specified by setting the
224
+ $ID environment variable. To list all backends of the current
225
+ website, run #{qcommand "website:backends"}.
226
+ MSG
227
+ end
228
+
229
+ def fetch_current!
230
+ id = require_id!
231
+ website.fetch_current!.backends.find(id)
232
+ end
233
+
234
+ def fetch_current
235
+ backends = website.fetch_current!.backends
236
+ (id = ENV["ID"]) ? backends.find(id) : backends.last
237
+ end
238
+
239
+ def fetch_several
240
+ backends = website.fetch_current!.backends
241
+ (id = ENV["ID"]) ? [backends.find(id)] : backends.all
242
+ end
243
+
244
+ def show_list(backends)
245
+ puts_list backends do |t|
246
+ t.col("Website") { |b| b.website.name }
247
+ t.col("Running on", :vps)
248
+ t.col("Running as", :user)
249
+ t.col("Instances", :num_instances)
250
+ t.col("Internal web port", :port)
251
+ end
252
+ end
253
+ end
254
+ end