webbynode 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of webbynode might be problematic. Click here for more details.
- data/Manifest +88 -4
- data/PostInstall.txt +42 -9
- data/README.rdoc +6 -0
- data/Rakefile +16 -19
- data/assets/webbynode.png +0 -0
- data/bin/webbynode +3 -3
- data/bin/wn +7 -0
- data/cucumber.yml +1 -0
- data/devver.rake +174 -0
- data/features/bootstrap.feature +17 -0
- data/features/step_definitions/command_steps.rb +14 -0
- data/features/support/env.rb +22 -0
- data/features/support/hooks.rb +8 -0
- data/{test/test_webbynode.rb → features/support/io_features.rb} +0 -0
- data/features/support/mocha.rb +15 -0
- data/lib/templates/api_token +14 -0
- data/lib/templates/backup +15 -0
- data/lib/templates/gitignore +4 -0
- data/lib/templates/help +53 -0
- data/lib/webbynode/api_client.rb +121 -0
- data/lib/webbynode/application.rb +21 -0
- data/lib/webbynode/command.rb +332 -0
- data/lib/webbynode/commands/add_backup.rb +33 -0
- data/lib/webbynode/commands/add_key.rb +24 -0
- data/lib/webbynode/commands/alias.rb +153 -0
- data/lib/webbynode/commands/change_dns.rb +29 -0
- data/lib/webbynode/commands/config.rb +15 -0
- data/lib/webbynode/commands/delete.rb +25 -0
- data/lib/webbynode/commands/help.rb +25 -0
- data/lib/webbynode/commands/init.rb +77 -0
- data/lib/webbynode/commands/push.rb +70 -0
- data/lib/webbynode/commands/remote.rb +28 -0
- data/lib/webbynode/commands/restart.rb +25 -0
- data/lib/webbynode/commands/start.rb +23 -0
- data/lib/webbynode/commands/stop.rb +23 -0
- data/lib/webbynode/commands/tasks.rb +149 -0
- data/lib/webbynode/commands/version.rb +8 -0
- data/lib/webbynode/commands/webbies.rb +30 -0
- data/lib/webbynode/git.rb +112 -0
- data/lib/webbynode/io.rb +175 -0
- data/lib/webbynode/notify.rb +19 -0
- data/lib/webbynode/option.rb +84 -0
- data/lib/webbynode/parameter.rb +27 -0
- data/lib/webbynode/properties.rb +43 -0
- data/lib/webbynode/push_and.rb +16 -0
- data/lib/webbynode/remote_executor.rb +21 -0
- data/lib/webbynode/server.rb +39 -0
- data/lib/webbynode/ssh.rb +65 -0
- data/lib/webbynode/ssh_keys.rb +36 -0
- data/lib/webbynode.rb +56 -0
- data/spec/fixtures/aliases +0 -0
- data/spec/fixtures/api/credentials +3 -0
- data/spec/fixtures/api/dns +30 -0
- data/spec/fixtures/api/dns_a_record +20 -0
- data/spec/fixtures/api/dns_a_record_already_exists +15 -0
- data/spec/fixtures/api/dns_a_record_error +13 -0
- data/spec/fixtures/api/dns_new_zone +17 -0
- data/spec/fixtures/api/webbies +26 -0
- data/spec/fixtures/api/webbies_unauthorized +12 -0
- data/spec/fixtures/api/webby +6 -0
- data/spec/fixtures/commands/tasks/after_push +3 -0
- data/spec/fixtures/fixture_helpers +2 -0
- data/spec/fixtures/git/config/210.11.13.12 +9 -0
- data/spec/fixtures/git/config/67.23.79.31 +9 -0
- data/spec/fixtures/git/config/67.23.79.32 +9 -0
- data/spec/fixtures/git/config/config +9 -0
- data/spec/fixtures/git/status/clean +2 -0
- data/spec/fixtures/git/status/dirty +9 -0
- data/spec/fixtures/pushand +2 -0
- data/spec/spec_helper.rb +58 -0
- data/spec/webbynode/api_client_spec.rb +227 -0
- data/spec/webbynode/application_spec.rb +50 -0
- data/spec/webbynode/command_spec.rb +285 -0
- data/spec/webbynode/commands/add_backup_spec.rb +66 -0
- data/spec/webbynode/commands/add_key_spec.rb +58 -0
- data/spec/webbynode/commands/alias_spec.rb +213 -0
- data/spec/webbynode/commands/change_dns_spec.rb +51 -0
- data/spec/webbynode/commands/config_spec.rb +22 -0
- data/spec/webbynode/commands/delete_spec.rb +78 -0
- data/spec/webbynode/commands/help_spec.rb +43 -0
- data/spec/webbynode/commands/init_spec.rb +326 -0
- data/spec/webbynode/commands/push_spec.rb +175 -0
- data/spec/webbynode/commands/remote_spec.rb +76 -0
- data/spec/webbynode/commands/tasks_spec.rb +288 -0
- data/spec/webbynode/commands/version_spec.rb +18 -0
- data/spec/webbynode/commands/webbies_spec.rb +27 -0
- data/spec/webbynode/git_spec.rb +310 -0
- data/spec/webbynode/io_spec.rb +198 -0
- data/spec/webbynode/option_spec.rb +48 -0
- data/spec/webbynode/parameter_spec.rb +70 -0
- data/spec/webbynode/push_and_spec.rb +28 -0
- data/spec/webbynode/remote_executor_spec.rb +25 -0
- data/spec/webbynode/server_spec.rb +101 -0
- data/webbynode.gemspec +25 -16
- metadata +182 -14
- data/lib/wn.rb +0 -106
- data/test/test_helper.rb +0 -9
- data/test/test_wn.rb +0 -220
@@ -0,0 +1,29 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class ChangeDns < Webbynode::Command
|
3
|
+
requires_initialization!
|
4
|
+
|
5
|
+
summary "Changes the DNS entry for this application"
|
6
|
+
parameter :dns_entry, "New DNS entry for this application"
|
7
|
+
|
8
|
+
add_alias "dns"
|
9
|
+
|
10
|
+
def execute
|
11
|
+
raise CommandError,
|
12
|
+
"Cannot change DNS because you have pending changes. Do a git commit or add changes to .gitignore." unless git.clean?
|
13
|
+
|
14
|
+
io.log "Changing DNS to #{param(:dns_entry)}...", :quiet_start
|
15
|
+
|
16
|
+
git.delete_file ".webbynode/config"
|
17
|
+
handle_dns param(:dns_entry)
|
18
|
+
|
19
|
+
app_name = io.app_name
|
20
|
+
io.create_file(".pushand", "#! /bin/bash\nphd $0 #{app_name} #{param(:dns_entry)}\n", true)
|
21
|
+
|
22
|
+
git.add ".pushand"
|
23
|
+
git.add ".webbynode/settings" if io.file_exists?(".webbynode/settings")
|
24
|
+
git.commit "Changed DNS to \"#{param(:dns_entry)}\""
|
25
|
+
|
26
|
+
io.log "Your application will start responding to #{param(:dns_entry)} after next deployment."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Config < Webbynode::Command
|
3
|
+
summary "Adds or changes your Webbynode API credentials"
|
4
|
+
option :email, "The email you use on Webbymanager"
|
5
|
+
option :token, "The API Token, found on Account section of Webbymanager"
|
6
|
+
|
7
|
+
def execute
|
8
|
+
value = {}
|
9
|
+
value[:email] = option(:email) if option(:email)
|
10
|
+
value[:token] = option(:token) if option(:token)
|
11
|
+
|
12
|
+
api.init_credentials(value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Delete < Webbynode::Command
|
3
|
+
summary "Removes the current application from your Webby"
|
4
|
+
option :force, "Skips confirmation and forces the deletion of the app"
|
5
|
+
|
6
|
+
add_alias "rm"
|
7
|
+
add_alias "remove"
|
8
|
+
|
9
|
+
def execute
|
10
|
+
unless pushand.present?
|
11
|
+
io.log("Ahn!? Hello, McFly, anybody home?", true)
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
app_name = pushand.parse_remote_app_name
|
16
|
+
if option(:force) or ask("Do you really want to delete application #{app_name} (y/n)? ").downcase == "y"
|
17
|
+
notify("Removing [#{app_name}] from your webby...")
|
18
|
+
remote_executor.exec "delete_app #{app_name} --force", true
|
19
|
+
notify("The application [#{app_name}] has been removed from your webby.\n\nThe webserver is restarting.")
|
20
|
+
else
|
21
|
+
puts "Aborted."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Help < Webbynode::Command
|
3
|
+
summary "Guess what? You're on it!"
|
4
|
+
parameter :command, "Command to get help on"
|
5
|
+
|
6
|
+
def execute
|
7
|
+
if param(:command) == "commands"
|
8
|
+
puts "usage: webbynode COMMAND"
|
9
|
+
puts
|
10
|
+
puts "Available commands:"
|
11
|
+
dir = File.join(File.expand_path(File.dirname(__FILE__)), "/*.rb")
|
12
|
+
Dir[dir].each do |file|
|
13
|
+
command = file.split("/").last
|
14
|
+
command.gsub!(/\.rb/, "")
|
15
|
+
|
16
|
+
puts " #{command.ljust(10)} #{Webbynode::Command.class_for(command).setting(:summary)}"
|
17
|
+
end
|
18
|
+
puts
|
19
|
+
puts "Try 'webbynode help COMMAND' for more information."
|
20
|
+
else
|
21
|
+
puts Help.for(param(:command)).help
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Init < Webbynode::Command
|
3
|
+
summary "Prepares the application on current folder for deployment"
|
4
|
+
parameter :webby, String, "Name or IP of the Webby to deploy to"
|
5
|
+
parameter :dns, String, "The DNS used for this application", :required => false
|
6
|
+
option :adddns, "Creates the DNS entries for the domain"
|
7
|
+
option :engine, "Sets the application engine for the app", :validate => { :in => ['php', 'rack', 'rails', 'rails3'] }
|
8
|
+
|
9
|
+
def execute
|
10
|
+
unless params.any?
|
11
|
+
io.log help
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
webby = param(:webby)
|
16
|
+
app_name = io.app_name
|
17
|
+
|
18
|
+
if param(:dns)
|
19
|
+
dns_entry = "#{param(:dns)}"
|
20
|
+
else
|
21
|
+
dns_entry = app_name
|
22
|
+
end
|
23
|
+
|
24
|
+
io.log "Initializing application #{app_name} #{dns_entry ? "with dns #{dns_entry}" : ""}", :start
|
25
|
+
|
26
|
+
if webby =~ /\b(?:\d{1,3}\.){3}\d{1,3}\b/
|
27
|
+
webby_ip = webby
|
28
|
+
else
|
29
|
+
begin
|
30
|
+
io.log "Retrieving IP for Webby #{webby}...", :action
|
31
|
+
webby_ip = api.ip_for(webby)
|
32
|
+
unless webby_ip
|
33
|
+
if (webbies = api.webbies.keys) and webbies.any?
|
34
|
+
raise CommandError,
|
35
|
+
"Couldn't find Webby '#{webby}' on your account. Your Webbies are: #{webbies.map { |w| "'#{w}'"}.to_phrase}."
|
36
|
+
else
|
37
|
+
raise CommandError, "You don't have any active Webbies on your account."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
io.log "Initializing directory structure...", :action
|
44
|
+
git.add_git_ignore unless io.file_exists?(".gitignore")
|
45
|
+
|
46
|
+
unless io.file_exists?(".pushand")
|
47
|
+
io.create_file(".pushand", "#! /bin/bash\nphd $0 #{app_name} #{dns_entry}\n", true)
|
48
|
+
end
|
49
|
+
|
50
|
+
unless io.directory?(".webbynode")
|
51
|
+
io.exec("mkdir -p .webbynode/tasks")
|
52
|
+
io.create_file(".webbynode/tasks/after_push", "")
|
53
|
+
io.create_file(".webbynode/tasks/before_push", "")
|
54
|
+
io.create_file(".webbynode/aliases", "")
|
55
|
+
io.create_file(".webbynode/config", "")
|
56
|
+
end
|
57
|
+
|
58
|
+
io.add_setting("engine", option(:engine)) if option(:engine)
|
59
|
+
|
60
|
+
unless git.present?
|
61
|
+
io.log "Initializing git and applying initial commit...", :action
|
62
|
+
git.init
|
63
|
+
git.add "."
|
64
|
+
git.commit "Initial commit"
|
65
|
+
end
|
66
|
+
|
67
|
+
io.log "Adding webbynode as git remote...", :action
|
68
|
+
git.add_remote "webbynode", webby_ip, app_name
|
69
|
+
|
70
|
+
handle_dns param(:dns) if option(:adddns)
|
71
|
+
|
72
|
+
io.log "Application #{app_name} ready for Rapid Deployment", :finish
|
73
|
+
rescue Webbynode::GitRemoteAlreadyExistsError
|
74
|
+
io.log "Application already initialized.", true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Push < Webbynode::Command
|
3
|
+
|
4
|
+
requires_initialization!
|
5
|
+
|
6
|
+
attr_accessor :app_name, :before_tasks, :after_tasks
|
7
|
+
|
8
|
+
add_alias "deploy"
|
9
|
+
|
10
|
+
summary "Sends pending changes on the current application to your Webby"
|
11
|
+
option :dirty, "Allows pushing even if the current application has git changes pending"
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
@before_tasks = Webbynode::Commands::Tasks.new
|
16
|
+
@after_tasks = Webbynode::Commands::Tasks.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute
|
20
|
+
unless option(:dirty)
|
21
|
+
raise CommandError,
|
22
|
+
"Cannot push because you have pending changes. Do a git commit or add changes to .gitignore." unless git.clean?
|
23
|
+
end
|
24
|
+
|
25
|
+
@app_name = pushand.parse_remote_app_name
|
26
|
+
|
27
|
+
# Ensures there are Task Files to read from
|
28
|
+
before_tasks.ensure_tasks_folder
|
29
|
+
|
30
|
+
# Reads out the "before push" tasks file to see if there are any tasks that must be performed
|
31
|
+
# It will perform the "before push" tasks if there are any available
|
32
|
+
before_tasks.read_tasks(Webbynode::Commands::Tasks::BeforePushTasksFile)
|
33
|
+
perform_before_tasks if before_tasks.has_tasks?
|
34
|
+
|
35
|
+
# Logs a initialization message to the user
|
36
|
+
# Pushes the application to Webbynode
|
37
|
+
io.log "Pushing #{app_name}", :start
|
38
|
+
io.exec("git push webbynode master", false)
|
39
|
+
|
40
|
+
# Reads out the "after push" tasks file to see if there are any tasks that must be performed
|
41
|
+
# It will perform the "after push" tasks if there are any available
|
42
|
+
after_tasks.read_tasks(Webbynode::Commands::Tasks::AfterPushTasksFile)
|
43
|
+
perform_after_tasks if after_tasks.has_tasks?
|
44
|
+
|
45
|
+
io.log "Finished pushing #{app_name}", :finish
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Performs the before push tasks locally
|
52
|
+
def perform_before_tasks
|
53
|
+
io.log "Performing Before Push Tasks...", :action
|
54
|
+
before_tasks.session_tasks.each do |task|
|
55
|
+
io.log " Performing Task: #{task}", :action
|
56
|
+
io.exec(task)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Performs the after push tasks remotely from the application root
|
61
|
+
def perform_after_tasks
|
62
|
+
io.log "Performing After Push Tasks...", :action
|
63
|
+
after_tasks.session_tasks.each do |task|
|
64
|
+
io.log " Performing Task: #{task}", :action
|
65
|
+
remote_executor.exec("cd #{pushand.parse_remote_app_name}; #{task}", true)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class NoOptionsProvided < StandardError; end
|
3
|
+
|
4
|
+
class Remote < Webbynode::Command
|
5
|
+
summary "Execute commands on your Webby for the current application"
|
6
|
+
|
7
|
+
requires_initialization!
|
8
|
+
requires_options!
|
9
|
+
|
10
|
+
parameter :command, Array, "Commands to execute"
|
11
|
+
|
12
|
+
def execute
|
13
|
+
unless server.application_pushed?
|
14
|
+
io.log "Before being able to run remote commands from your webby, you must first push your application to it."
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
# Parses Pushand File and returns remote application name
|
19
|
+
remote_app_name = pushand.parse_remote_app_name
|
20
|
+
|
21
|
+
# Notify the user
|
22
|
+
io.log("Performing the requested remote command..", true)
|
23
|
+
|
24
|
+
# Executes the command on the remote server inside the application root folder
|
25
|
+
remote_executor.exec("cd #{remote_app_name}; #{param_values.join(" ")}", true)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Restart < Webbynode::Command
|
3
|
+
summary "Reboots your Webby"
|
4
|
+
add_alias "reboot"
|
5
|
+
|
6
|
+
requires_initialization!
|
7
|
+
|
8
|
+
def execute
|
9
|
+
exit if no?("Are you sure you wish to restart your webby? (y/n)")
|
10
|
+
|
11
|
+
api.webbies.each do |webby|
|
12
|
+
if webby[1][:ip].eql?(git.parse_remote_ip)
|
13
|
+
if webby[1][:status].eql?("on")
|
14
|
+
puts "#{webby[0]} will now be rebooted!"
|
15
|
+
api.post("/webby/#{webby[1][:name]}/reboot")
|
16
|
+
else
|
17
|
+
puts "#{webby[0]} is starting up!"
|
18
|
+
api.post("/webby/#{webby[1][:name]}/start")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Start < Webbynode::Command
|
3
|
+
summary "Starts your Webby, when it's off"
|
4
|
+
add_alias "boot"
|
5
|
+
|
6
|
+
requires_initialization!
|
7
|
+
|
8
|
+
def execute
|
9
|
+
exit if no?("Are you sure you wish to start your webby? (y/n)")
|
10
|
+
|
11
|
+
api.webbies.each do |webby|
|
12
|
+
if webby[1][:ip].eql?(git.parse_remote_ip)
|
13
|
+
unless webby[1][:status].eql?("on")
|
14
|
+
puts "#{webby[0]} is starting up!"
|
15
|
+
api.post("/webby/#{webby[1][:name]}/start")
|
16
|
+
else
|
17
|
+
puts "#{webby[0]} is already started up."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Stop < Webbynode::Command
|
3
|
+
summary "Shuts down your Webby"
|
4
|
+
add_alias "shutdown"
|
5
|
+
|
6
|
+
requires_initialization!
|
7
|
+
|
8
|
+
def execute
|
9
|
+
exit if no?("Are you sure you wish to shutdown your webby? (y/n)")
|
10
|
+
|
11
|
+
api.webbies.each do |webby|
|
12
|
+
if webby[1][:ip].eql?(git.parse_remote_ip)
|
13
|
+
unless webby[1][:status].eql?("off")
|
14
|
+
puts "#{webby[0]} will now shutdown!"
|
15
|
+
api.post("/webby/#{webby[1][:name]}/shutdown")
|
16
|
+
else
|
17
|
+
puts "#{webby[0]} is already shutdown."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Tasks < Webbynode::Command
|
3
|
+
requires_initialization!
|
4
|
+
|
5
|
+
attr_accessor :action, :type, :command, :session_file, :session_tasks
|
6
|
+
|
7
|
+
summary "Manages tasks executed before or after you push your changes"
|
8
|
+
parameter :action, String, "add, remove or show.", :required => true, :validate => { :in => ["add", "remove", "show"] }
|
9
|
+
parameter :type, String, "before_push or after_push.", :required => true, :validate => { :in => ["before_push", "after_push"]}
|
10
|
+
parameter :command, Array, "Task to perform.", :required => false
|
11
|
+
|
12
|
+
# Constants
|
13
|
+
# Paths to the webbynode task files
|
14
|
+
TasksPath = ".webbynode/tasks"
|
15
|
+
BeforePushTasksFile = ".webbynode/tasks/before_push"
|
16
|
+
AfterPushTasksFile = ".webbynode/tasks/after_push"
|
17
|
+
|
18
|
+
def initialize(*args)
|
19
|
+
super
|
20
|
+
@session_tasks = Array.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute
|
24
|
+
|
25
|
+
# Ensures that the tasks folder (.webbynode/tasks) is present
|
26
|
+
# Will create the task files if they are not present
|
27
|
+
ensure_tasks_folder
|
28
|
+
|
29
|
+
# Should parse the parameters
|
30
|
+
parse_parameters
|
31
|
+
|
32
|
+
# Sets the current path, extracted from @type
|
33
|
+
set_session_file
|
34
|
+
|
35
|
+
# Reads out the currently set tasks
|
36
|
+
read_tasks(session_file)
|
37
|
+
|
38
|
+
# Initializes either [add], [remove] or [show] depending on user input
|
39
|
+
send(action)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
# Checks to see if the session_tasks has any tasks
|
44
|
+
def has_tasks?
|
45
|
+
return true unless session_tasks.empty?
|
46
|
+
false
|
47
|
+
end
|
48
|
+
|
49
|
+
# Reads the tasks straight from the specified file and stores them inside (in order)
|
50
|
+
# the session_tasks method.
|
51
|
+
def read_tasks(file)
|
52
|
+
@session_tasks = []
|
53
|
+
io.read_file(file).each_line do |line|
|
54
|
+
@session_tasks << line.gsub(/\n/,'') unless line.blank?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Ensures the presence of the .webbynode/tasks folder
|
59
|
+
# Will create the necessary task files when they are not available
|
60
|
+
def ensure_tasks_folder
|
61
|
+
io.exec('mkdir .webbynode/tasks') unless io.directory?(".webbynode/tasks")
|
62
|
+
%w[before_push after_push].each do |file|
|
63
|
+
io.exec("touch .webbynode/tasks/#{file}") unless io.file_exists?(".webbynode/tasks/#{file}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Gets invoked if the user specified [add] for @action
|
70
|
+
def add
|
71
|
+
append_task(command)
|
72
|
+
write_tasks
|
73
|
+
show_tasks
|
74
|
+
end
|
75
|
+
|
76
|
+
# Gets invoked if the user specified [remove] for @action
|
77
|
+
def remove
|
78
|
+
delete_task(command.to_i)
|
79
|
+
write_tasks
|
80
|
+
show_tasks
|
81
|
+
end
|
82
|
+
|
83
|
+
# Gets invoked if the user specified [show] for @action
|
84
|
+
def show
|
85
|
+
show_tasks
|
86
|
+
end
|
87
|
+
|
88
|
+
# Appends a task to the session_tasks method.
|
89
|
+
def append_task(task)
|
90
|
+
@session_tasks << task
|
91
|
+
end
|
92
|
+
|
93
|
+
# Overwrites the existing file with the new tasks list
|
94
|
+
# This will always be done from the session_tasks.
|
95
|
+
def write_tasks
|
96
|
+
io.open_file(session_file, "w") do |file|
|
97
|
+
session_tasks.each do |task|
|
98
|
+
file.write "#{task}\n"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Removes a task based on the number(index) provided.
|
104
|
+
# example: delete_task(2)
|
105
|
+
# This will remove whatever task is 3rd in the session_tasks array.
|
106
|
+
def delete_task(i)
|
107
|
+
filtered_tasks = []
|
108
|
+
session_tasks.each_with_index do |task, index|
|
109
|
+
filtered_tasks << task unless index.eql?(i)
|
110
|
+
end
|
111
|
+
@session_tasks = filtered_tasks
|
112
|
+
end
|
113
|
+
|
114
|
+
# Reads out each task (in order) either from the session_tasks method
|
115
|
+
# or straight from the physical file on the filesystem and outputs it directly
|
116
|
+
# in the console to the user for feedback.
|
117
|
+
def show_tasks(from_file = false)
|
118
|
+
read_tasks(session_file, true) if from_file
|
119
|
+
if session_tasks.empty?
|
120
|
+
io.log_and_exit "You haven't set up any tasks for \"#{type.gsub('_',' ').capitalize}\"."
|
121
|
+
end
|
122
|
+
io.log "These are the current tasks for \"#{type.gsub('_',' ').capitalize}\":"
|
123
|
+
session_tasks.each_with_index do |task, index|
|
124
|
+
io.log "[#{index}] #{task}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Determines the selected file that will be used for the current session.
|
129
|
+
# This will be stored inside the session_file method.
|
130
|
+
def set_session_file
|
131
|
+
case @type
|
132
|
+
when 'before_push' then sf = BeforePushTasksFile
|
133
|
+
when 'after_push' then sf = AfterPushTasksFile
|
134
|
+
end
|
135
|
+
@session_file = sf
|
136
|
+
end
|
137
|
+
|
138
|
+
# Parses the parameters and stores the params inside 3 different methods
|
139
|
+
# [action] represents: [add/remove/show]
|
140
|
+
# [type] represents: [before/after_create before/after_push]
|
141
|
+
# [command] represents: The remote command that should get executed
|
142
|
+
def parse_parameters
|
143
|
+
@action = param(:action)
|
144
|
+
@type = param(:type)
|
145
|
+
@command = param(:command).join(" ")
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Webbynode::Commands
|
2
|
+
class Webbies < Webbynode::Command
|
3
|
+
summary "Lists the Webbies you currently own"
|
4
|
+
|
5
|
+
def execute
|
6
|
+
puts "Fetching list of your Webbies..."
|
7
|
+
puts ""
|
8
|
+
|
9
|
+
header = " "
|
10
|
+
header << "Webbies".ljust(16)
|
11
|
+
header << "IP".ljust(16)
|
12
|
+
header << "Node".ljust(10)
|
13
|
+
header << "Plan".ljust(16)
|
14
|
+
header << "Status".ljust(15)
|
15
|
+
|
16
|
+
puts header
|
17
|
+
|
18
|
+
api.webbies.each_pair do |name, webby|
|
19
|
+
str = " "
|
20
|
+
str << name.ljust(16)
|
21
|
+
str << webby[:ip].ljust(16)
|
22
|
+
str << webby[:node].ljust(10)
|
23
|
+
str << webby[:plan].ljust(16)
|
24
|
+
str << webby[:status]
|
25
|
+
|
26
|
+
puts str
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Webbynode
|
2
|
+
class GitError < StandardError; end
|
3
|
+
class GitNotRepoError < StandardError; end
|
4
|
+
class GitRemoteDoesNotExistError < StandardError; end
|
5
|
+
class GitRemoteAlreadyExistsError < StandardError; end
|
6
|
+
|
7
|
+
class Git
|
8
|
+
attr_accessor :config, :remote_ip
|
9
|
+
|
10
|
+
def present?
|
11
|
+
io.directory?(".git")
|
12
|
+
end
|
13
|
+
|
14
|
+
def io
|
15
|
+
@@io ||= Webbynode::Io.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def init
|
19
|
+
exec("git init") do |output|
|
20
|
+
# this indicates init was properly executed
|
21
|
+
output =~ /^Initialized empty Git repository in/
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def clean?
|
26
|
+
io.exec("git status") =~ /working directory clean/
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_file(file)
|
30
|
+
return unless io.file_exists?(file)
|
31
|
+
io.delete_file(file)
|
32
|
+
exec "git rm #{file} > /dev/null 2>&1"
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_git_ignore
|
36
|
+
io.create_from_template(".gitignore", "gitignore")
|
37
|
+
end
|
38
|
+
|
39
|
+
def add(what)
|
40
|
+
exec "git add #{what}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_remote(name, host, repo)
|
44
|
+
exec("git remote add #{name} git@#{host}:#{repo}") do |output|
|
45
|
+
# raise an exception if remote already exists
|
46
|
+
raise GitRemoteAlreadyExistsError, output if output =~ /remote \w+ already exists/
|
47
|
+
|
48
|
+
# success if output is empty
|
49
|
+
output.nil? or output.empty?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def commit(comments)
|
54
|
+
comments.gsub! /"/, '\"'
|
55
|
+
exec("git commit -m \"#{comments}\"") do |output|
|
56
|
+
output =~ /#{comments}/ or output =~ /nothing to commit/
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_config
|
61
|
+
return @config if defined?(@config)
|
62
|
+
if present? and remote_webbynode?
|
63
|
+
config = {}
|
64
|
+
current = {}
|
65
|
+
File.open(".git/config").each_line do |line|
|
66
|
+
case line
|
67
|
+
when /^\[(\w+)(?: "(.+)")*\]/
|
68
|
+
key, subkey = $1, $2
|
69
|
+
current = (config[key] ||= {})
|
70
|
+
current = (current[subkey] ||= {}) if subkey
|
71
|
+
else
|
72
|
+
key, value = line.strip.split(' = ')
|
73
|
+
current[key] = value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@config = config
|
77
|
+
else
|
78
|
+
raise Webbynode::GitNotRepoError, "Git repository does not exist." unless present?
|
79
|
+
raise Webbynode::GitRemoteDoesNotExistError, "Webbynode has not been initialized." unless remote_webbynode?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_remote_ip
|
84
|
+
@config ||= parse_config
|
85
|
+
@remote_ip ||= ($2 if @config["remote"]["webbynode"]["url"] =~ /^(\w+)@(.+):(.+)$/) if @config
|
86
|
+
end
|
87
|
+
|
88
|
+
def remote_webbynode?
|
89
|
+
return true if io.exec('git remote') =~ /webbynode/
|
90
|
+
false
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def exec(cmd, &blk)
|
96
|
+
handle_output io.exec(cmd), &blk
|
97
|
+
end
|
98
|
+
|
99
|
+
def handle_output(output, &blk)
|
100
|
+
raise GitNotRepoError, output if output =~ /Not a git repository/
|
101
|
+
|
102
|
+
if blk
|
103
|
+
raise GitError, output unless blk.call(output)
|
104
|
+
else
|
105
|
+
raise GitError, output unless output.nil? or output.empty?
|
106
|
+
end
|
107
|
+
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|