webbynode 0.2.5.beta2 → 1.0.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.

Files changed (41) hide show
  1. data/Manifest +10 -3
  2. data/Rakefile +7 -5
  3. data/changelog.rdoc +83 -0
  4. data/lib/templates/backup +1 -1
  5. data/lib/webbynode/command.rb +3 -1
  6. data/lib/webbynode/commands/add_key.rb +2 -2
  7. data/lib/webbynode/commands/addons.rb +84 -0
  8. data/lib/webbynode/commands/init.rb +13 -1
  9. data/lib/webbynode/commands/open.rb +21 -0
  10. data/lib/webbynode/engines/django.rb +5 -0
  11. data/lib/webbynode/engines/rails3.rb +1 -0
  12. data/lib/webbynode/git.rb +29 -5
  13. data/lib/webbynode/io.rb +10 -2
  14. data/lib/webbynode/option.rb +19 -4
  15. data/lib/webbynode/parameter.rb +1 -1
  16. data/lib/webbynode/properties.rb +22 -3
  17. data/lib/webbynode/remote_executor.rb +14 -4
  18. data/lib/webbynode/server.rb +1 -1
  19. data/lib/webbynode/ssh.rb +6 -3
  20. data/lib/webbynode.rb +3 -1
  21. data/spec/fixtures/git/config/new_210.11.13.12 +9 -0
  22. data/spec/fixtures/git/config/new_67.23.79.31 +9 -0
  23. data/spec/fixtures/git/config/new_67.23.79.32 +9 -0
  24. data/spec/fixtures/git/config/new_config +9 -0
  25. data/spec/webbynode/commands/add_key_spec.rb +3 -3
  26. data/spec/webbynode/commands/addons_spec.rb +181 -0
  27. data/spec/webbynode/commands/init_spec.rb +33 -0
  28. data/spec/webbynode/commands/open_spec.rb +31 -0
  29. data/spec/webbynode/engines/django_spec.rb +12 -0
  30. data/spec/webbynode/git_spec.rb +59 -23
  31. data/spec/webbynode/io_spec.rb +28 -4
  32. data/spec/webbynode/option_spec.rb +13 -2
  33. data/spec/webbynode/properties_spec.rb +29 -0
  34. data/spec/webbynode/remote_executor_spec.rb +34 -10
  35. data/spec/webbynode/server_spec.rb +1 -1
  36. data/spec/webbynode/ssh_spec.rb +34 -0
  37. data/webbynode.gemspec +12 -8
  38. metadata +41 -16
  39. data/History.txt +0 -4
  40. data/Manifest.txt +0 -11
  41. data/devver.rake +0 -174
data/Manifest CHANGED
@@ -1,6 +1,4 @@
1
- History.txt
2
1
  Manifest
3
- Manifest.txt
4
2
  PostInstall.txt
5
3
  README.rdoc
6
4
  Rakefile
@@ -9,7 +7,6 @@ bin/webbynode
9
7
  bin/wn
10
8
  changelog.rdoc
11
9
  cucumber.yml.old
12
- devver.rake
13
10
  inactive_features/bootstrap.feature
14
11
  inactive_features/step_definitions/command_steps.rb
15
12
  inactive_features/support/env.rb
@@ -27,6 +24,7 @@ lib/webbynode/attribute_accessors.rb
27
24
  lib/webbynode/command.rb
28
25
  lib/webbynode/commands/add_backup.rb
29
26
  lib/webbynode/commands/add_key.rb
27
+ lib/webbynode/commands/addons.rb
30
28
  lib/webbynode/commands/alias.rb
31
29
  lib/webbynode/commands/apps.rb
32
30
  lib/webbynode/commands/change_dns.rb
@@ -34,6 +32,7 @@ lib/webbynode/commands/config.rb
34
32
  lib/webbynode/commands/delete.rb
35
33
  lib/webbynode/commands/help.rb
36
34
  lib/webbynode/commands/init.rb
35
+ lib/webbynode/commands/open.rb
37
36
  lib/webbynode/commands/push.rb
38
37
  lib/webbynode/commands/remote.rb
39
38
  lib/webbynode/commands/restart.rb
@@ -79,6 +78,10 @@ spec/fixtures/git/config/67.23.79.31
79
78
  spec/fixtures/git/config/67.23.79.32
80
79
  spec/fixtures/git/config/config
81
80
  spec/fixtures/git/config/config_5
81
+ spec/fixtures/git/config/new_210.11.13.12
82
+ spec/fixtures/git/config/new_67.23.79.31
83
+ spec/fixtures/git/config/new_67.23.79.32
84
+ spec/fixtures/git/config/new_config
82
85
  spec/fixtures/git/status/clean
83
86
  spec/fixtures/git/status/dirty
84
87
  spec/fixtures/pushand
@@ -89,6 +92,7 @@ spec/webbynode/application_spec.rb
89
92
  spec/webbynode/command_spec.rb
90
93
  spec/webbynode/commands/add_backup_spec.rb
91
94
  spec/webbynode/commands/add_key_spec.rb
95
+ spec/webbynode/commands/addons_spec.rb
92
96
  spec/webbynode/commands/alias_spec.rb
93
97
  spec/webbynode/commands/apps_spec.rb
94
98
  spec/webbynode/commands/change_dns_spec.rb
@@ -96,6 +100,7 @@ spec/webbynode/commands/config_spec.rb
96
100
  spec/webbynode/commands/delete_spec.rb
97
101
  spec/webbynode/commands/help_spec.rb
98
102
  spec/webbynode/commands/init_spec.rb
103
+ spec/webbynode/commands/open_spec.rb
99
104
  spec/webbynode/commands/push_spec.rb
100
105
  spec/webbynode/commands/remote_spec.rb
101
106
  spec/webbynode/commands/tasks_spec.rb
@@ -112,7 +117,9 @@ spec/webbynode/git_spec.rb
112
117
  spec/webbynode/io_spec.rb
113
118
  spec/webbynode/option_spec.rb
114
119
  spec/webbynode/parameter_spec.rb
120
+ spec/webbynode/properties_spec.rb
115
121
  spec/webbynode/push_and_spec.rb
116
122
  spec/webbynode/remote_executor_spec.rb
117
123
  spec/webbynode/server_spec.rb
124
+ spec/webbynode/ssh_spec.rb
118
125
  webbynode.gemspec
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
 
5
5
  require 'echoe'
6
6
 
7
- Echoe.new('webbynode', '0.2.5.beta2') do |p|
7
+ Echoe.new('webbynode', '1.0.0') do |p|
8
8
  p.description = "Webbynode Deployment Gem"
9
9
  p.url = "http://webbynode.com"
10
10
  p.author = "Felipe Coury"
@@ -15,6 +15,7 @@ Echoe.new('webbynode', '0.2.5.beta2') do |p|
15
15
  ['net-ssh', '>=2.0.20'],
16
16
  ['highline', '>=1.5.2'],
17
17
  ['httparty', '>=0.4.5'],
18
+ ['launchy', '>=0.3.7'],
18
19
  ['domainatrix','>=0.0.7'],
19
20
  ]
20
21
  # p.dependencies = [
@@ -29,11 +30,12 @@ Echoe.new('webbynode', '0.2.5.beta2') do |p|
29
30
  Webbynode Rapid Deployment Gem
30
31
  -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
31
32
 
32
- This deployment engine is highly experimental and
33
- should be considered beta code for now.
33
+ Thank you for installing Webbynode gem. You're now
34
+ able to deploy and manage your applications from
35
+ the comfort of your command line.
34
36
 
35
- For a quickstart:
36
- http://guides.webbynode.com/articles/rapidapps
37
+ Please read our guide for a quickstart:
38
+ http://guides.webbynode.com/articles/rapidapps/
37
39
 
38
40
  "
39
41
  end
data/changelog.rdoc CHANGED
@@ -1,13 +1,96 @@
1
1
  = CHANGELOG
2
2
 
3
+ == 2010-08-04 Felipe Coury
4
+
5
+ * Properties class properly saves array values. Fixes #23
6
+
7
+ == 2010-08-03 Felipe Coury
8
+
9
+ * Fixed a failing test by pending it with explanatory message.
10
+ * Fixed bug where database.yml was not being excluded from git.
11
+
12
+ == 2010-07-28 Felipe Coury
13
+
14
+ * Added Beanstalk
15
+
16
+ == 2010-07-22 Felipe Coury
17
+
18
+ * Fixed spelling in addons command
19
+ * New installation message
20
+
21
+ == 2010-07-21 Felipe Coury
22
+
23
+ * Prevents errors if addons param is malformed
24
+
25
+ == 2010-07-20 Felipe Coury
26
+
27
+ * Added `wn open' command. Closes #22
28
+ * Adds SSH key when initializing. Closes #15
29
+ * Added support for addons. Closes #20
30
+
31
+ == 2010-07-04 Felipe Coury
32
+
33
+ * Error message when using Django engine and settings.py isn't found
34
+ * Updated gemspec and Manifest
35
+ * Now all commands work with an alternate SSH port when wn init --port=PORT is used. Fixed a small bug on options validation. Fixes #19
36
+ * Handles connection refused when attempting to run commands
37
+ * Changed AWS S3 back help text to point to the correct URL. Fixes #17
38
+
39
+ == 2010-07-01 Felipe Coury
40
+
41
+ * Bumped gem version to 0.2.5.beta2.
42
+ * Added Django initialization code for handling .gitignore and settings.template.py creation.
43
+ * Taken Rails-specific code out of init command.
44
+ * Added prepare to Engine and extracted Gemfile detection code to Rails3 engine class.
45
+ * Added engine_id, engine_name and git_excluded specs for engines
46
+ * Invalid engine shows error message and triggers interactive engine selection.
47
+ * Starting of Engine-specific preparation and validation code (WIP)
48
+ * Refactoring on the Engine detection methods.
49
+ * Engine detection refactoring (work in progress).
50
+
51
+ == 2010-06-30 Felipe Coury
52
+
53
+ * Fixed order of settings
54
+ * Detects pontential problems before engine detection
55
+ * Engine detection refactoring
56
+ * Marked gem as 0.2.5.beta1. Closes #12. Closes #13.
57
+
58
+ == 2010-06-29 Felipe Coury
59
+
60
+ * Made webbynode gem compatible with Windows.
61
+
62
+ == 2010-06-28 Felipe Coury
63
+
64
+ * Merge commit '0.2.4.1'
65
+ * Removed jcode as a dependency. Fixes #8.
66
+ * Removed cucumber.yml for the time being
67
+ * Improved wn init feedback
68
+
69
+ == 2010-06-27 Felipe Coury
70
+
71
+ * When user has only one Webby, assumes it when `init' command is used. When user has multiple Webbies and the param is omitted, shows a list of user's Webbies.
72
+ * Removed features temporarily
73
+ * Init command now takes DNS entry as an option (--dns=xyz) and started simplification of wn init, making the webby parameter optional if user only have one Webby.
74
+ * Fixed option parsing to allow xyz.abc.def
75
+ * Renamed feature for the time being
76
+
77
+ == 2010-06-26 Felipe Coury
78
+
79
+ * Rapp automatic updates support Command `wn apps' - lists all the current apps on a Webby Bumped Gem version
80
+
3
81
  == 2010-06-24 Felipe Coury
4
82
 
83
+ * Added changelog
5
84
  * Rails 3 autodetection
6
85
  * Small typo on Gemfile error message
7
86
  * Uses bundler to check for sqlite3-ruby dependency in Gemfile. If found, issues an error message with proper instructions. Closes #6.
8
87
  * Fixed version command
9
88
  * Stops tracking db/schema.rb and config/database.yml if there is an existing git repo. Closes #7. Doesn't allow init to run if current app in on a dirty git state.
10
89
 
90
+ == 2010-06-24 Michael van Rooijen
91
+
92
+ * Adjusted the Gemfile error text.
93
+
11
94
  == 2010-06-23 Felipe Coury
12
95
 
13
96
  * Adds db/schema.rb and config/database.yml to .gitignore. Closes #7.
data/lib/templates/backup CHANGED
@@ -3,7 +3,7 @@ Webbynode Rapid App Backup
3
3
  This service will backup a dump of your application Database and the contents
4
4
  of your application folder to a bucket on Amazon S3. If you don't have an
5
5
  Amazon S3 account or if you don't know how to create one, please check our
6
- guide on http://guides.webbynode.com/rapid.
6
+ guide on http://guides.webbynode.com/articles/rapidapps/backup.html.
7
7
 
8
8
  DISCLAIMER: Backing up to S3 will incur on a charge by Amazon according to the
9
9
  terms of the services contract you accepted when signing up to their services.
@@ -204,7 +204,8 @@ module Webbynode
204
204
  end
205
205
 
206
206
  def remote_executor
207
- @remote_executor ||= Webbynode::RemoteExecutor.new(git.parse_remote_ip)
207
+ git.parse_remote_ip
208
+ @remote_executor ||= Webbynode::RemoteExecutor.new(git.remote_ip, git.remote_port)
208
209
  end
209
210
 
210
211
  def pushand
@@ -311,6 +312,7 @@ module Webbynode
311
312
  end
312
313
 
313
314
  settings[:parameters].each { |p| p.validate! }
315
+ settings[:options].each { |p| p.validate! }
314
316
  end
315
317
 
316
318
  def handle_dns(dns)
@@ -1,3 +1,5 @@
1
+ LocalSshKey = "#{ENV['HOME']}/.ssh/id_rsa.pub"
2
+
1
3
  module Webbynode::Commands
2
4
  class AddKey < Webbynode::Command
3
5
  requires_initialization!
@@ -5,8 +7,6 @@ module Webbynode::Commands
5
7
  summary "Adds your ssh public key to your Webby, making deployments easy"
6
8
  option :passphrase, "If present, passphrase will be used when creating a new SSH key", :take => :words
7
9
 
8
- LocalSshKey = "#{ENV['HOME']}/.ssh/id_rsa.pub"
9
-
10
10
  add_alias "addkey"
11
11
 
12
12
  def execute
@@ -0,0 +1,84 @@
1
+ module Webbynode::Commands
2
+ class Addons < Webbynode::Command
3
+ SUPPORTED_ADDONS = ["mongodb", "redis", "memcached", "beanstalkd"]
4
+
5
+ summary "Manages you application's add-ons"
6
+ parameter :action, "add, remove or show",
7
+ :required => false, :validate => { :in => ['add', 'remove', 'show']}
8
+ parameter :addon, "name of the addon",
9
+ :required => false, :validate => { :in => SUPPORTED_ADDONS }
10
+
11
+ add_alias "addon"
12
+
13
+ def execute
14
+ show_summary and return unless action = param(:action)
15
+ send(action)
16
+ end
17
+
18
+ private
19
+
20
+ def add
21
+ return unless validate_addon('add')
22
+
23
+ if @addons.include?(@addon)
24
+ io.log("Add-on '#{@addon}' was already included")
25
+ else
26
+ @addons << @addon
27
+ io.add_multi_setting 'addons', @addons
28
+ io.log("Add-on '#{@addon}' added")
29
+ end
30
+ end
31
+
32
+ def remove
33
+ return unless validate_addon('remove')
34
+
35
+ if @addons.include?(@addon)
36
+ @addons.delete(@addon)
37
+ io.add_multi_setting 'addons', @addons
38
+ io.log("Add-on '#{@addon}' removed")
39
+ else
40
+ io.log("Add-on '#{@addon}' not installed")
41
+ end
42
+ end
43
+
44
+ def validate_addon(verb)
45
+ unless @addon = param(:addon)
46
+ io.log("Missing addon to #{verb}. Type 'wn addons' for a list of available addons.")
47
+ return false
48
+ end
49
+
50
+ unless SUPPORTED_ADDONS.include?(@addon)
51
+ io.log("Addon #{@addon} doesn't exist. Type 'wn addons' for a list of available addons.")
52
+ return false
53
+ end
54
+
55
+ @addons = io.load_setting('addons') || []
56
+ @addons = [] unless @addons.is_a?(Array)
57
+ @addons
58
+ end
59
+
60
+ def show_summary
61
+ io.log('Available add-ons:')
62
+ io.log("")
63
+ io.log(' Key Name Description')
64
+ io.log(' ------------ ----------- ------------------------')
65
+ io.log(' beanstalkd Beanstalk Simple, fast workqueue service')
66
+ io.log(' memcached Memcached Distributed memory object caching system')
67
+ io.log(' mongodb MongoDB Document based database engine')
68
+ io.log(' redis Redis Advanced key-value store')
69
+ io.log("")
70
+
71
+ addons = io.load_setting("addons")
72
+ if addons && addons.is_a?(Array) && addons.any?
73
+ io.log('Currently selected add-ons:')
74
+ io.log('')
75
+ io.log(" #{addons.join(', ')}")
76
+ else
77
+ io.log("No add-ons currently selected. Use 'wn addons add <name>' to add.")
78
+ end
79
+ io.log('')
80
+
81
+ true
82
+ end
83
+ end
84
+ end
@@ -4,6 +4,7 @@ module Webbynode::Commands
4
4
  parameter :webby, String, "Name or IP of the Webby to deploy to", :required => false
5
5
  option :dns, String, "The DNS used for this application"
6
6
  option :adddns, "Creates the DNS entries for the domain"
7
+ option :port, "Specifies an alternate SSH port to connect to Webby", :validate => :integer
7
8
  option :engine, "Sets the application engine for the app", :validate => { :in => ['php', 'rack', 'rails', 'rails3'] }
8
9
 
9
10
  def execute
@@ -74,11 +75,22 @@ module Webbynode::Commands
74
75
  end
75
76
 
76
77
  io.log "Adding webbynode as git remote..."
77
- git.add_remote "webbynode", webby_ip, app_name
78
+ options = ["webbynode", webby_ip, app_name]
79
+ options << option(:port).to_i if option(:port)
80
+
81
+ Webbynode::Server.new(webby_ip).add_ssh_key LocalSshKey, nil
82
+
83
+ git.add_remote *options
78
84
 
79
85
  handle_dns option(:dns) if option(:adddns)
80
86
 
81
87
  io.log "Application #{app_name} ready for Rapid Deployment", :finish
88
+ rescue Webbynode::InvalidAuthentication
89
+ io.log "Could not connect to webby: invalid authentication.", true
90
+
91
+ rescue Webbynode::PermissionError
92
+ io.log "Could not create an SSH key: permission error.", true
93
+
82
94
  rescue Webbynode::GitRemoteAlreadyExistsError
83
95
  io.log "Application already initialized."
84
96
  end
@@ -0,0 +1,21 @@
1
+ require 'launchy'
2
+
3
+ module Webbynode::Commands
4
+ class Open < Webbynode::Command
5
+ requires_initialization!
6
+
7
+ summary "Opens the current application in your browser"
8
+
9
+ def execute
10
+ mapping = "/var/webbynode/mappings/#{io.app_name}.conf"
11
+ url = remote_executor.exec("test -f #{mapping} && cat #{mapping}", false).strip.chomp
12
+
13
+ if url && !url.empty?
14
+ url = "http://#{url}"
15
+ Launchy.open url
16
+ else
17
+ io.log "Application not found or not deployed."
18
+ end
19
+ end
20
+ end
21
+ end
@@ -5,6 +5,11 @@ module Webbynode::Engines
5
5
  git_excludes 'settings.py', '*.pyc', '*.pyo', 'docs/_build'
6
6
 
7
7
  def prepare
8
+ unless io.file_exists?('settings.py')
9
+ raise Webbynode::Command::CommandError,
10
+ "Couldn't create the settings template because settings.py was not found. Please check and try again."
11
+ end
12
+
8
13
  unless io.file_exists?('settings.template.py')
9
14
  io.log 'Creating settings.template.py from your settings.py...'
10
15
  io.copy_file 'settings.py', 'settings.template.py'
@@ -10,6 +10,7 @@ module Webbynode::Engines
10
10
 
11
11
  def prepare
12
12
  check_gemfile
13
+ super
13
14
  end
14
15
 
15
16
  private
data/lib/webbynode/git.rb CHANGED
@@ -6,7 +6,7 @@ module Webbynode
6
6
  class GitRemoteCouldNotRemoveError < StandardError; end
7
7
 
8
8
  class Git
9
- attr_accessor :config, :remote_ip
9
+ attr_accessor :config, :remote_ip, :remote_port
10
10
 
11
11
  def present?
12
12
  io.directory?(".git")
@@ -45,8 +45,10 @@ module Webbynode
45
45
  exec "git add #{what}"
46
46
  end
47
47
 
48
- def add_remote(name, host, repo)
49
- exec("git remote add #{name} git@#{host}:#{repo}") do |output|
48
+ def add_remote(name, host, repo, port=22)
49
+ home = RemoteExecutor.new(host, port).remote_home
50
+
51
+ exec("git remote add #{name} ssh://git@#{host}:#{port}#{home}/#{repo}") do |output|
50
52
  # raise an exception if remote already exists
51
53
  raise GitRemoteAlreadyExistsError, output if output =~ /remote \w+ already exists/
52
54
 
@@ -108,9 +110,31 @@ module Webbynode
108
110
  end
109
111
  end
110
112
 
113
+ def init_config
114
+ @config ||= parse_config
115
+ end
116
+
117
+ def parse_remote_url
118
+ init_config
119
+ @remote_url ||= @config["remote"]["webbynode"]["url"]
120
+ end
121
+
111
122
  def parse_remote_ip
112
- @config ||= parse_config
113
- @remote_ip ||= ($2 if @config["remote"]["webbynode"]["url"] =~ /^(\w+)@(.+):(.+)$/) if @config
123
+ init_config
124
+
125
+ # new remote format
126
+ if parse_remote_url =~ /^ssh:\/\/(\w+)@(.+)\/(.+)$/
127
+ if $2 =~ /(.*):(\d*)\/(.*)$/
128
+ @remote_ip ||= $1
129
+ @remote_port ||= $2.to_i
130
+ @remote_home ||= "/#{$3}"
131
+ end
132
+ else
133
+ @remote_ip ||= ($2 if @config["remote"]["webbynode"]["url"] =~ /^(\w+)@(.+):(.+)$/) if @config
134
+ @remote_port ||= 22
135
+ end
136
+
137
+ @remote_ip
114
138
  end
115
139
 
116
140
  def remote_exists?(remote)
data/lib/webbynode/io.rb CHANGED
@@ -137,8 +137,8 @@ module Webbynode
137
137
  end
138
138
 
139
139
  def create_local_key(passphrase="")
140
- unless File.exists?(Webbynode::Commands::AddKey::LocalSshKey)
141
- exec "ssh-keygen -t rsa -N \"#{passphrase}\" -f #{Webbynode::Commands::AddKey::LocalSshKey}"
140
+ unless File.exists?(LocalSshKey)
141
+ exec "ssh-keygen -t rsa -N \"#{passphrase}\" -f #{LocalSshKey}"
142
142
  end
143
143
  end
144
144
 
@@ -207,6 +207,14 @@ module Webbynode
207
207
  with_setting { |s| s[key] = value }
208
208
  end
209
209
 
210
+ def add_multi_setting(key, values)
211
+ with_setting { |s| s[key] = "(#{values.join(" ")})" }
212
+ end
213
+
214
+ def load_setting(key)
215
+ properties(".webbynode/settings")[key]
216
+ end
217
+
210
218
  def config_multi_add(key, new_value)
211
219
  raise "Missing Webbynode config file" unless file_exists?(".webbynode/config")
212
220
  config = read_yaml(".webbynode/config")
@@ -14,7 +14,9 @@ module Webbynode
14
14
  @value = nil
15
15
  @options = args.pop if args.last.is_a?(Hash)
16
16
  @options ||= {}
17
- @options[:required] = true if @options[:required].nil?
17
+
18
+ @original_options = @options.clone
19
+ @options[:required] = false if @options[:required].nil?
18
20
 
19
21
  @name = args[0]
20
22
  if args[1].is_a?(String)
@@ -33,15 +35,28 @@ module Webbynode
33
35
  end
34
36
 
35
37
  def valid?
38
+ return true if !required? and value.nil?
36
39
  @errors = []
37
40
  if (validations = @options[:validate])
38
- validations.each_pair do |key, value|
39
- @errors << send("#{key}_error", value) unless send(key, value)
41
+ if validations.is_a?(Hash)
42
+ validations.each_pair do |key, value|
43
+ @errors << send("#{key}_error", value) unless send(key, value)
44
+ end
45
+ else
46
+ @errors << send("#{validations}_error", value) unless send(validations, value)
40
47
  end
41
48
  end
42
49
  @errors.empty?
43
50
  end
44
51
 
52
+ def integer(value)
53
+ Integer(value) rescue false
54
+ end
55
+
56
+ def integer_error(value)
57
+ "Invalid value '#{value}' for #{self.class.name.split("::").last.downcase} '#{self.name}'. It should be an integer."
58
+ end
59
+
45
60
  def in(allowed_values)
46
61
  allowed_values.include?(self.value)
47
62
  end
@@ -70,7 +85,7 @@ module Webbynode
70
85
  end
71
86
 
72
87
  def required?
73
- @options[:required]
88
+ @options[:required] == true
74
89
  end
75
90
 
76
91
  def take
@@ -2,7 +2,7 @@ module Webbynode
2
2
  class Parameter < Webbynode::Option
3
3
  def initialize(*args)
4
4
  super
5
- @options[:required] = true if @options[:required].nil?
5
+ @options[:required] = true if @original_options[:required].nil?
6
6
  end
7
7
 
8
8
  def validate!
@@ -12,12 +12,21 @@ module Webbynode
12
12
 
13
13
  begin
14
14
  IO.foreach(file) do |line|
15
- self[$1.strip.to_s] = $2.strip if line = ~ /([^=]*)=(.*)\/\/(.*)/ || line =~ /([^=]*)=(.*)/
15
+ if line = ~ /([^=]*)=(.*)\/\/(.*)/ || line =~ /([^=]*)=(.*)/
16
+ key = $1.strip.to_s
17
+ value = $2.strip
18
+
19
+ if value =~ /^\((.*)\)$/
20
+ value = $1.split(' ')
21
+ end
22
+
23
+ self[key] = value
24
+ end
16
25
  end
17
26
  rescue
18
27
  end
19
28
  end
20
-
29
+
21
30
  def to_s
22
31
  output = "File name #{@file}\n"
23
32
  self.each { |key, value| output += " #{key} = #{value}\n" }
@@ -36,8 +45,18 @@ module Webbynode
36
45
 
37
46
  def save
38
47
  file = File.new(@file, "w+")
39
- self.each { |key, value| file.puts "#{key}=#{value}\n" }
48
+ self.converted.each { |key, value| file.puts "#{key}=#{value}\n" }
40
49
  file.close
41
50
  end
51
+
52
+ def converted
53
+ hash = self.clone
54
+ hash.each do |k, v|
55
+ if v.is_a?(Array)
56
+ hash[k] = "(#{v.join(" ")})"
57
+ end
58
+ end
59
+ hash
60
+ end
42
61
  end
43
62
  end
@@ -1,21 +1,31 @@
1
1
  module Webbynode
2
2
  class RemoteExecutor
3
- attr_accessor :ip
3
+ attr_accessor :ip, :port
4
4
 
5
- def initialize(ip)
5
+ def initialize(ip, port=nil)
6
6
  @ip = ip
7
+ @port = port
7
8
  end
8
9
 
9
10
  def ssh
10
- @ssh ||= Ssh.new(ip)
11
+ @ssh ||= Ssh.new(ip, port)
11
12
  end
12
13
 
13
14
  def create_folder(folder)
14
15
  ssh.execute "mkdir -p #{folder}"
15
16
  end
16
17
 
18
+ def remote_home
19
+ exec('pwd').strip
20
+ end
21
+
17
22
  def exec(cmd, echo=false, exit_code=false)
18
- ssh.execute(cmd, echo, exit_code)
23
+ begin
24
+ ssh.execute(cmd, echo, exit_code)
25
+ rescue Errno::ECONNREFUSED
26
+ raise Webbynode::Command::CommandError,
27
+ "Could not connect to #{@ip}. Please check your settings and your network connection and try again."
28
+ end
19
29
  end
20
30
  end
21
31
  end
@@ -28,7 +28,7 @@ module Webbynode
28
28
  remote_executor.create_folder("~/.ssh")
29
29
 
30
30
  key_contents = io.read_file(key_file)
31
- remote_executor.exec "echo \"#{key_contents}\" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"
31
+ remote_executor.exec "grep \"#{key_contents}\" ~/.ssh/authorized_keys || (echo \"#{key_contents}\" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys)"
32
32
  end
33
33
 
34
34
  def application_pushed?
data/lib/webbynode/ssh.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  module Webbynode
2
2
  class Ssh
3
- def initialize(remote_ip)
3
+ attr_accessor :remote_ip, :port
4
+
5
+ def initialize(remote_ip, port=22)
4
6
  @remote_ip = remote_ip
7
+ @port = port
5
8
  end
6
9
 
7
10
  def io
@@ -11,13 +14,13 @@ module Webbynode
11
14
  def connect
12
15
  raise "No IP given" unless @remote_ip
13
16
  @conn = nil if @conn and @conn.closed?
14
- @conn ||= Net::SSH.start(@remote_ip, 'git', :auth_methods => %w(publickey hostbased))
17
+ @conn ||= Net::SSH.start(@remote_ip, 'git', :port => @port, :auth_methods => %w(publickey hostbased))
15
18
  rescue Net::SSH::AuthenticationFailed
16
19
  HighLine.track_eof = false
17
20
 
18
21
  begin
19
22
  @password ||= ask("Enter your deployment password for #{@remote_ip}: ") { |q| q.echo = '' }
20
- @conn ||= Net::SSH.start(@remote_ip, 'git', :password => @password)
23
+ @conn ||= Net::SSH.start(@remote_ip, 'git', :port => @port, :password => @password)
21
24
  rescue Net::SSH::AuthenticationFailed
22
25
  io.log "Could not connect to server: invalid authentication.", true
23
26
  exit