Flucti-flucti-cli 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +7 -0
- data/README.mdown +24 -0
- data/Rakefile +56 -0
- data/TODO.txt +19 -0
- data/bin/flucti +4 -0
- data/flucti-cli.gemspec +46 -0
- data/lib/flucti.rb +20 -0
- data/lib/flucti/api_access.rb +56 -0
- data/lib/flucti/cli.rb +107 -0
- data/lib/flucti/parameters.rb +37 -0
- data/lib/flucti/resources.rb +41 -0
- data/lib/flucti/resources/account.rb +7 -0
- data/lib/flucti/resources/app_type.rb +18 -0
- data/lib/flucti/resources/backend.rb +28 -0
- data/lib/flucti/resources/basic_resource.rb +16 -0
- data/lib/flucti/resources/container.rb +15 -0
- data/lib/flucti/resources/db_server.rb +38 -0
- data/lib/flucti/resources/domain.rb +8 -0
- data/lib/flucti/resources/general.rb +14 -0
- data/lib/flucti/resources/mail_client.rb +7 -0
- data/lib/flucti/resources/mail_server.rb +7 -0
- data/lib/flucti/resources/port_forwarding.rb +15 -0
- data/lib/flucti/resources/port_forwarding/services +13921 -0
- data/lib/flucti/resources/ssh_details.rb +96 -0
- data/lib/flucti/resources/webserver.rb +9 -0
- data/lib/flucti/resources/website.rb +9 -0
- data/lib/flucti/tasks.rb +3 -0
- data/lib/flucti/tasks/apikey_tasks.rb +57 -0
- data/lib/flucti/tasks/apptype_tasks.rb +264 -0
- data/lib/flucti/tasks/connect_pack.rb +161 -0
- data/lib/flucti/tasks/db_tasks.rb +158 -0
- data/lib/flucti/tasks/mail_tasks.rb +104 -0
- data/lib/flucti/tasks/miscellaneous_tasks.rb +6 -0
- data/lib/flucti/tasks/progress_tasks.rb +24 -0
- data/lib/flucti/tasks/sshkey_tasks.rb +151 -0
- data/lib/flucti/tasks/vps/firewall_tasks.rb +84 -0
- data/lib/flucti/tasks/vps_tasks.rb +37 -0
- data/lib/flucti/tasks/webserver_tasks.rb +154 -0
- data/lib/flucti/tasks/website/apptype_tasks.rb +42 -0
- data/lib/flucti/tasks/website/backends/instances_tasks.rb +37 -0
- data/lib/flucti/tasks/website/backends_tasks.rb +254 -0
- data/lib/flucti/tasks/website/capfile_tasks.rb +41 -0
- data/lib/flucti/tasks/website/domains_tasks.rb +107 -0
- data/lib/flucti/tasks/website_tasks.rb +221 -0
- data/lib/flucti/utilities.rb +20 -0
- data/lib/flucti/utilities/connection_error_handling.rb +50 -0
- data/lib/flucti/utilities/core_ext.rb +35 -0
- data/lib/flucti/utilities/list_displayer.rb +57 -0
- data/lib/flucti/utilities/miscellaneous.rb +65 -0
- data/lib/flucti/utilities/progress_bar.rb +17 -0
- data/lib/flucti/utilities/table.rb +25 -0
- data/lib/flucti/utilities/task_packing.rb +10 -0
- data/lib/flucti/utilities/user_interface.rb +117 -0
- data/lib/vendor/ruby-progressbar-0.9/lib/ChangeLog +113 -0
- data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.en.rd +103 -0
- data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.ja.rd +100 -0
- data/lib/vendor/ruby-progressbar-0.9/lib/progressbar.rb +236 -0
- data/lib/vendor/ruby-progressbar-0.9/lib/test.rb +105 -0
- data/test/flucti/resources_test.rb +32 -0
- data/test/flucti/tasks_test.rb +28 -0
- data/test/flucti/utilities/miscellaneous_test.rb +54 -0
- data/test/flucti/utilities/table_test.rb +28 -0
- data/test/flucti/utilities/user_interface_test.rb +161 -0
- data/test/test_helper.rb +5 -0
- metadata +221 -0
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2008-2009 Roman Le Négrate
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.mdown
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Flucti-CLI
|
2
|
+
|
3
|
+
Flucti-CLI is the command-line utility that eases installation, configuration and deployment of websites on one or several VPS('s) leased from [Flucti][].
|
4
|
+
|
5
|
+
See the [documentation site][Documentation] for more information.
|
6
|
+
|
7
|
+
## Status
|
8
|
+
|
9
|
+
* It's fairly complete at the moment.
|
10
|
+
* Some big features are still missing, like UNIX user management, database user management, more complete firewall configuration.
|
11
|
+
* Unit tests still needs to be written too, but I'm still wondering how to test tasks in a clean way.
|
12
|
+
|
13
|
+
## Target
|
14
|
+
|
15
|
+
This utility is relevant for [Flucti][] clients only, given that it acts as a layer on top of the Flucti API which requires one to have an account there.
|
16
|
+
|
17
|
+
But for what it's worth, this utility can still be of use to other people as its source code is likely to be a good usage example of the [WebService](http://github.com/Roman2K/web-service) library.
|
18
|
+
|
19
|
+
## Credits
|
20
|
+
|
21
|
+
Written by [Roman Le Négrate](http://roman.flucti.com) ([contact](mailto:roman.lenegrate@gmail.com)). Released under the MIT license: see the `LICENSE` file.
|
22
|
+
|
23
|
+
[Flucti]: http://www.flucti.com
|
24
|
+
[Documentation]: http://doc.flucti.com
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
|
3
|
+
Echoe.new('flucti-cli', '0.1.16') do |p|
|
4
|
+
p.description = "Command-line interface for managing Flucti VPS's"
|
5
|
+
p.url = "http://doc.flucti.com/cli"
|
6
|
+
p.author = "Roman Le Négrate"
|
7
|
+
p.email = "roman.lenegrate@gmail.com"
|
8
|
+
p.ignore_pattern = "*.gemspec"
|
9
|
+
p.dependencies = ["capistrano ~>2.5", "web-service", "capistrano-fixes"]
|
10
|
+
p.development_dependencies = ["mocha"]
|
11
|
+
p.rdoc_options = %w(--main README.mdown --inline-source --line-numbers --charset UTF-8)
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :check do
|
15
|
+
task :namespacing do
|
16
|
+
point_out_source_files "Absence of namespacing" do |file|
|
17
|
+
case file.to_s.split('.').first
|
18
|
+
when /(\b|_)tasks$/, /_pack$/, /\bvendor\b/
|
19
|
+
false
|
20
|
+
else
|
21
|
+
declaration =
|
22
|
+
file.read.
|
23
|
+
split("\n").
|
24
|
+
reject { |line| line.strip.empty? || line =~ /^\s*(?:require\b|\$:)/ }.
|
25
|
+
first
|
26
|
+
file if declaration !~ /\Amodule Flucti$/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
task :constants do
|
32
|
+
point_out_source_files "Malformed constant names" do |file|
|
33
|
+
malformed = file.read.scan(/\bflucti\b/i).flatten - ["Flucti", "flucti"]
|
34
|
+
[file, *malformed] if malformed.any?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def point_out_source_files(checking)
|
39
|
+
require 'pathname'
|
40
|
+
result =
|
41
|
+
Pathname.glob('lib/**/*.rb').
|
42
|
+
map { |file| yield file }.
|
43
|
+
select { |result| result }.
|
44
|
+
map { |file, *rest|
|
45
|
+
rest.any? ? "! %-30s %s" % ["#{file}:", rest.join(' ')] : "! #{file}"
|
46
|
+
}
|
47
|
+
if result.any?
|
48
|
+
puts(checking, *result)
|
49
|
+
else
|
50
|
+
puts "%-30s (none)" % "#{checking}:"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
task :check => ['check:namespacing', 'check:constants']
|
55
|
+
|
56
|
+
task :default => [:check, :test]
|
data/TODO.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
* Add a task that allows for modifying the number of instances of a certain backend, on-the-fly (without interruption of service).
|
2
|
+
|
3
|
+
* Add support for one metadata file per service configuration:
|
4
|
+
|
5
|
+
That would allow for specifying the name of a service configuration (currently inferred from the prefix *_start.sh) and most importantly, their single-instance nature.
|
6
|
+
|
7
|
+
This would be a boolean value which determines whether to allow more than 1 instance of a service to be spawned.
|
8
|
+
|
9
|
+
For example:
|
10
|
+
- Rack-compatible applications like Rails and Sinatra apps can be spawned in multiple instances as nginx spreads requests across these instances.
|
11
|
+
- However, it doesn't make sense for PHP (FCGI) backends to have more than 1 instance since nginx only connects to 1 FCGI server.
|
12
|
+
|
13
|
+
The NUM_INSTANCES variables can still be used by the service configuration to spawn more instances its own way. In the case of PHP, both the PHP_FCGI_CHILDREN and PHP_FCGI_MAX_REQUESTS can be set accordingly.
|
14
|
+
|
15
|
+
* Add a task for configuring mail clients: once a VPS has a mail server set up (mail:server:setup) it can send mails through itself, but other VPS's still need to be configured to go through that mail server mails coming from them. Such a task would take care of it.
|
16
|
+
|
17
|
+
* Add a task for changing the hostname of a VPS.
|
18
|
+
|
19
|
+
* In SshDetails::AccountBinding#check_for_presence_of_ssh, fix the invalid indentation of connection details.
|
data/bin/flucti
ADDED
data/flucti-cli.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{flucti-cli}
|
5
|
+
s.version = "0.1.16"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Roman Le N\303\251grate"]
|
9
|
+
s.date = %q{2009-03-25}
|
10
|
+
s.default_executable = %q{flucti}
|
11
|
+
s.description = %q{Command-line interface for managing Flucti VPS's}
|
12
|
+
s.email = %q{roman.lenegrate@gmail.com}
|
13
|
+
s.executables = ["flucti"]
|
14
|
+
s.extra_rdoc_files = ["bin/flucti", "lib/flucti/api_access.rb", "lib/flucti/cli.rb", "lib/flucti/parameters.rb", "lib/flucti/resources/account.rb", "lib/flucti/resources/app_type.rb", "lib/flucti/resources/backend.rb", "lib/flucti/resources/basic_resource.rb", "lib/flucti/resources/container.rb", "lib/flucti/resources/db_server.rb", "lib/flucti/resources/domain.rb", "lib/flucti/resources/general.rb", "lib/flucti/resources/mail_client.rb", "lib/flucti/resources/mail_server.rb", "lib/flucti/resources/port_forwarding/services", "lib/flucti/resources/port_forwarding.rb", "lib/flucti/resources/ssh_details.rb", "lib/flucti/resources/webserver.rb", "lib/flucti/resources/website.rb", "lib/flucti/resources.rb", "lib/flucti/tasks/apikey_tasks.rb", "lib/flucti/tasks/apptype_tasks.rb", "lib/flucti/tasks/connect_pack.rb", "lib/flucti/tasks/db_tasks.rb", "lib/flucti/tasks/mail_tasks.rb", "lib/flucti/tasks/miscellaneous_tasks.rb", "lib/flucti/tasks/progress_tasks.rb", "lib/flucti/tasks/sshkey_tasks.rb", "lib/flucti/tasks/vps/firewall_tasks.rb", "lib/flucti/tasks/vps_tasks.rb", "lib/flucti/tasks/webserver_tasks.rb", "lib/flucti/tasks/website/apptype_tasks.rb", "lib/flucti/tasks/website/backends/instances_tasks.rb", "lib/flucti/tasks/website/backends_tasks.rb", "lib/flucti/tasks/website/capfile_tasks.rb", "lib/flucti/tasks/website/domains_tasks.rb", "lib/flucti/tasks/website_tasks.rb", "lib/flucti/tasks.rb", "lib/flucti/utilities/connection_error_handling.rb", "lib/flucti/utilities/core_ext.rb", "lib/flucti/utilities/list_displayer.rb", "lib/flucti/utilities/miscellaneous.rb", "lib/flucti/utilities/progress_bar.rb", "lib/flucti/utilities/table.rb", "lib/flucti/utilities/task_packing.rb", "lib/flucti/utilities/user_interface.rb", "lib/flucti/utilities.rb", "lib/flucti.rb", "lib/vendor/ruby-progressbar-0.9/lib/ChangeLog", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.en.rd", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.ja.rd", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.rb", "lib/vendor/ruby-progressbar-0.9/lib/test.rb", "LICENSE", "README.mdown", "TODO.txt"]
|
15
|
+
s.files = ["bin/flucti", "lib/flucti/api_access.rb", "lib/flucti/cli.rb", "lib/flucti/parameters.rb", "lib/flucti/resources/account.rb", "lib/flucti/resources/app_type.rb", "lib/flucti/resources/backend.rb", "lib/flucti/resources/basic_resource.rb", "lib/flucti/resources/container.rb", "lib/flucti/resources/db_server.rb", "lib/flucti/resources/domain.rb", "lib/flucti/resources/general.rb", "lib/flucti/resources/mail_client.rb", "lib/flucti/resources/mail_server.rb", "lib/flucti/resources/port_forwarding/services", "lib/flucti/resources/port_forwarding.rb", "lib/flucti/resources/ssh_details.rb", "lib/flucti/resources/webserver.rb", "lib/flucti/resources/website.rb", "lib/flucti/resources.rb", "lib/flucti/tasks/apikey_tasks.rb", "lib/flucti/tasks/apptype_tasks.rb", "lib/flucti/tasks/connect_pack.rb", "lib/flucti/tasks/db_tasks.rb", "lib/flucti/tasks/mail_tasks.rb", "lib/flucti/tasks/miscellaneous_tasks.rb", "lib/flucti/tasks/progress_tasks.rb", "lib/flucti/tasks/sshkey_tasks.rb", "lib/flucti/tasks/vps/firewall_tasks.rb", "lib/flucti/tasks/vps_tasks.rb", "lib/flucti/tasks/webserver_tasks.rb", "lib/flucti/tasks/website/apptype_tasks.rb", "lib/flucti/tasks/website/backends/instances_tasks.rb", "lib/flucti/tasks/website/backends_tasks.rb", "lib/flucti/tasks/website/capfile_tasks.rb", "lib/flucti/tasks/website/domains_tasks.rb", "lib/flucti/tasks/website_tasks.rb", "lib/flucti/tasks.rb", "lib/flucti/utilities/connection_error_handling.rb", "lib/flucti/utilities/core_ext.rb", "lib/flucti/utilities/list_displayer.rb", "lib/flucti/utilities/miscellaneous.rb", "lib/flucti/utilities/progress_bar.rb", "lib/flucti/utilities/table.rb", "lib/flucti/utilities/task_packing.rb", "lib/flucti/utilities/user_interface.rb", "lib/flucti/utilities.rb", "lib/flucti.rb", "lib/vendor/ruby-progressbar-0.9/lib/ChangeLog", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.en.rd", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.ja.rd", "lib/vendor/ruby-progressbar-0.9/lib/progressbar.rb", "lib/vendor/ruby-progressbar-0.9/lib/test.rb", "LICENSE", "Manifest", "Rakefile", "README.mdown", "test/flucti/resources_test.rb", "test/flucti/tasks_test.rb", "test/flucti/utilities/miscellaneous_test.rb", "test/flucti/utilities/table_test.rb", "test/flucti/utilities/user_interface_test.rb", "test/test_helper.rb", "TODO.txt", "flucti-cli.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://doc.flucti.com/cli}
|
18
|
+
s.rdoc_options = ["--main", "README.mdown", "--inline-source", "--line-numbers", "--charset", "UTF-8"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{flucti-cli}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{Command-line interface for managing Flucti VPS's}
|
23
|
+
s.test_files = ["test/flucti/resources_test.rb", "test/flucti/tasks_test.rb", "test/flucti/utilities/miscellaneous_test.rb", "test/flucti/utilities/table_test.rb", "test/flucti/utilities/user_interface_test.rb", "test/test_helper.rb"]
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
+
s.specification_version = 2
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_runtime_dependency(%q<capistrano>, ["~> 2.5"])
|
31
|
+
s.add_runtime_dependency(%q<web-service>, [">= 0"])
|
32
|
+
s.add_runtime_dependency(%q<capistrano-fixes>, [">= 0"])
|
33
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<capistrano>, ["~> 2.5"])
|
36
|
+
s.add_dependency(%q<web-service>, [">= 0"])
|
37
|
+
s.add_dependency(%q<capistrano-fixes>, [">= 0"])
|
38
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
39
|
+
end
|
40
|
+
else
|
41
|
+
s.add_dependency(%q<capistrano>, ["~> 2.5"])
|
42
|
+
s.add_dependency(%q<web-service>, [">= 0"])
|
43
|
+
s.add_dependency(%q<capistrano-fixes>, [">= 0"])
|
44
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
45
|
+
end
|
46
|
+
end
|
data/lib/flucti.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift *Dir[File.dirname(__FILE__) + '/vendor/*/lib']
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'pathname'
|
5
|
+
require 'web_service'
|
6
|
+
|
7
|
+
module Flucti
|
8
|
+
autoload :Utilities, 'flucti/utilities'
|
9
|
+
autoload :Parameters, 'flucti/parameters'
|
10
|
+
autoload :APIAccess, 'flucti/api_access'
|
11
|
+
autoload :Resources, 'flucti/resources'
|
12
|
+
autoload :CLI, 'flucti/cli'
|
13
|
+
|
14
|
+
def self.boot
|
15
|
+
Resources.configure!
|
16
|
+
APIAccess.configure!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Flucti::Utilities::CoreExt.apply!
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Flucti
|
2
|
+
module APIAccess
|
3
|
+
extend self
|
4
|
+
extend Utilities
|
5
|
+
|
6
|
+
HOST = "api.flucti.com".freeze
|
7
|
+
|
8
|
+
def site
|
9
|
+
site_with_api_key(Parameters.fetch(:api_key) || (api_key_tasks.switch; Parameters.fetch(:api_key)))
|
10
|
+
end
|
11
|
+
|
12
|
+
def site_with_api_key(key)
|
13
|
+
WebService::Site.new("http://#{key}@#{HOST}")
|
14
|
+
end
|
15
|
+
|
16
|
+
def configure!
|
17
|
+
if (init = Parameters.store_dir / "init.rb").file?
|
18
|
+
load(init)
|
19
|
+
end
|
20
|
+
Resources::BasicResource.site = site
|
21
|
+
Resources::BasicResource.extend DeniedAccessRescue
|
22
|
+
end
|
23
|
+
|
24
|
+
def solve_denied_access!
|
25
|
+
puts_title "Access denied"
|
26
|
+
puts_long <<-MSG
|
27
|
+
You API key seems invalid. If you reset it recently, please enter the
|
28
|
+
new one at the prompt below. Otherwise, please contact us at
|
29
|
+
#{SUPPORT_EMAIL_ADDR} so that we can sort it out.
|
30
|
+
MSG
|
31
|
+
api_key_tasks.prompt_and_store_key
|
32
|
+
configure!
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def api_key_tasks
|
38
|
+
@api_key_tasks ||= begin
|
39
|
+
require "capistrano/configuration"
|
40
|
+
tasks = Capistrano::Configuration.new
|
41
|
+
tasks.extend Utilities
|
42
|
+
tasks.load File.dirname(__FILE__) + '/tasks/apikey_tasks.rb'
|
43
|
+
tasks.apikey
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module DeniedAccessRescue
|
48
|
+
def request(*args)
|
49
|
+
super
|
50
|
+
rescue WebService::UnauthorizedAccess
|
51
|
+
APIAccess.solve_denied_access!
|
52
|
+
retry
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/flucti/cli.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'capistrano/cli'
|
2
|
+
require 'progressbar'
|
3
|
+
|
4
|
+
module Flucti
|
5
|
+
module CLI
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def start
|
9
|
+
adjust_environment
|
10
|
+
reinterpret_help_option
|
11
|
+
Flucti.boot
|
12
|
+
|
13
|
+
cli = Capistrano::CLI.new(ARGV)
|
14
|
+
cli.parse_options!
|
15
|
+
cli.options[:verbose] = Capistrano::Logger::INFO
|
16
|
+
cli.execute!
|
17
|
+
end
|
18
|
+
|
19
|
+
def tasks
|
20
|
+
adjust_environment
|
21
|
+
config = Capistrano::Configuration.new
|
22
|
+
config.load File.dirname(__FILE__) + '/tasks.rb'
|
23
|
+
return config
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def adjust_environment
|
29
|
+
expose_constants
|
30
|
+
fix_cap_recipe_loading
|
31
|
+
fix_cap_tasks_brief_descriptions
|
32
|
+
fix_cap_help_messages
|
33
|
+
allow_for_lazy_env_var_naming
|
34
|
+
end
|
35
|
+
|
36
|
+
def expose_constants
|
37
|
+
Object.class_eval do
|
38
|
+
include Flucti
|
39
|
+
include Flucti::Resources
|
40
|
+
include Flucti::Utilities
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Force Capistrano::CLI to load the needed recipe files, and only them.
|
45
|
+
def fix_cap_recipe_loading
|
46
|
+
override 'Capistrano::CLI::Execute#load_recipes' do
|
47
|
+
def load_recipes(config)
|
48
|
+
config.load(File.dirname(__FILE__) + '/tasks.rb')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Fix brief description of tasks to allow the first sentence to be spanned
|
54
|
+
# over multiple lines.
|
55
|
+
def fix_cap_tasks_brief_descriptions
|
56
|
+
override 'Capistrano::CLI::Help#output_columns' do
|
57
|
+
def output_columns
|
58
|
+
Flucti::Utilities::UserInterface.terminal_width - 3
|
59
|
+
end
|
60
|
+
end
|
61
|
+
override 'Capistrano::TaskDefinition#brief_description' do
|
62
|
+
def brief_description(max_length=nil)
|
63
|
+
brief = (description[/\A.*?\.(?=\s|$)/m] || description).gsub(/\n+/, ' ')
|
64
|
+
if max_length && brief.length > max_length
|
65
|
+
brief = brief[0,max_length-3] + "..."
|
66
|
+
end
|
67
|
+
brief
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Make help messages refer to the current command instead of the hard-coded
|
73
|
+
# `cap' one.
|
74
|
+
def fix_cap_help_messages
|
75
|
+
override 'Capistrano::CLI::Help#puts' do
|
76
|
+
def puts(*lines)
|
77
|
+
super(*lines.map { |line| line.to_s.gsub(/\bcap\b/, Flucti::Utilities::Miscellaneous.command) })
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Fix letter-casing for environment variable assignments.
|
83
|
+
def allow_for_lazy_env_var_naming
|
84
|
+
ARGV.each_with_index { |arg, pos| ARGV[pos] = arg.sub(/^(\w+)(=)/) { $1.upcase + $2 } }
|
85
|
+
ENV.each { |key, value| ENV[key.upcase] ||= value }
|
86
|
+
end
|
87
|
+
|
88
|
+
# Replace the default help message with a list of tasks.
|
89
|
+
def reinterpret_help_option
|
90
|
+
if ARGV.empty? || %w(-h --help).map { |opt| ARGV.delete(opt) }.any?
|
91
|
+
ARGV.unshift '-vT'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def override(fqn, &block)
|
98
|
+
name, method = fqn.to_s.split('#', 2)
|
99
|
+
if mod = Object.class_eval("#{name} if defined? #{name}") and (Kernel.respond_to?(method) || [:public, :protected, :private].any? { |v| mod.send("#{v}_method_defined?", method) })
|
100
|
+
mod.module_eval(&block)
|
101
|
+
else
|
102
|
+
require 'capistrano/version'
|
103
|
+
raise "This library is incompatible with the current version of Capistrano (#{Capistrano::Version::STRING}). Failed to override `#{fqn}'."
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Flucti
|
2
|
+
module Parameters
|
3
|
+
extend self
|
4
|
+
extend Utilities
|
5
|
+
|
6
|
+
def store_dir
|
7
|
+
@store_dir ||= begin
|
8
|
+
options = []
|
9
|
+
options << Pathname(ENV['APPDATA']) / 'Flucti' if ENV['APPDATA']
|
10
|
+
options << Pathname(ENV['HOME']) / '.flucti' if ENV['HOME']
|
11
|
+
located = options.find { |dir| dir.directory? } || options.find { |dir| dir.dirname.directory? }
|
12
|
+
located ||= Pathname(Dir.tmpdir) / 'flucti'
|
13
|
+
located.mkpath
|
14
|
+
located
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def data_store
|
19
|
+
@data_store ||= store_dir / 'parameters.yml'
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch(key)
|
23
|
+
cache[key.to_s]
|
24
|
+
end
|
25
|
+
|
26
|
+
def store(key, value)
|
27
|
+
cache[key.to_s] = value
|
28
|
+
data_store.open("w") { |f| f << YAML.dump(cache) }
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def cache
|
34
|
+
@cache ||= (YAML.load_file(data_store) if data_store.exist?) || {}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Flucti
|
2
|
+
module Resources
|
3
|
+
def self.configure!
|
4
|
+
ENV['LOGLEVEL'] = 'debug' if ENV['DEBUG']
|
5
|
+
WebService.logger.level = Logger.const_get((ENV['LOGLEVEL'] || 'error').upcase)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.autoload_from(name, file)
|
9
|
+
autoload(name, "flucti/resources/#{file}")
|
10
|
+
end
|
11
|
+
|
12
|
+
autoload_from :BasicResource, 'basic_resource'
|
13
|
+
|
14
|
+
autoload_from :Container, 'container'
|
15
|
+
autoload_from :VPS, 'container'
|
16
|
+
autoload_from :Vps, 'container'
|
17
|
+
|
18
|
+
autoload_from :PortForwarding, 'port_forwarding'
|
19
|
+
autoload_from :Website, 'website'
|
20
|
+
autoload_from :Domain, 'domain'
|
21
|
+
autoload_from :Webserver, 'webserver'
|
22
|
+
autoload_from :MailServer, 'mail_server'
|
23
|
+
autoload_from :MailClient, 'mail_client'
|
24
|
+
|
25
|
+
autoload_from :AppType, 'app_type'
|
26
|
+
autoload_from :ServiceConfig, 'app_type'
|
27
|
+
|
28
|
+
autoload_from :Backend, 'backend'
|
29
|
+
autoload_from :InstallError, 'backend'
|
30
|
+
autoload_from :RootInstallError, 'backend'
|
31
|
+
|
32
|
+
autoload_from :DbServer, 'db_server'
|
33
|
+
autoload_from :Database, 'db_server'
|
34
|
+
|
35
|
+
autoload_from :Account, 'account'
|
36
|
+
autoload_from :SshDetails, 'ssh_details'
|
37
|
+
autoload_from :APIKey, 'general'
|
38
|
+
autoload_from :Progress, 'general'
|
39
|
+
autoload_from :SshKey, 'general'
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Flucti
|
2
|
+
module Resources
|
3
|
+
class AppType < BasicResource
|
4
|
+
self.attribute_for_to_s = :name
|
5
|
+
has_many :service_configs
|
6
|
+
end
|
7
|
+
|
8
|
+
class ServiceConfig < BasicResource
|
9
|
+
belongs_to :app_type
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
start = start_script if attribute_set? :start_script
|
13
|
+
finish = finish_script if attribute_set? :finish_script
|
14
|
+
"#{name} (start: #{start.to_s.length} bytes, finish: #{finish.to_s.length} bytes)"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|