vito 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rvmrc +1 -0
  4. data/README.md +33 -7
  5. data/Rakefile +35 -0
  6. data/Vagrantfile +1 -1
  7. data/bin/vito +7 -2
  8. data/docs/manual.md +79 -0
  9. data/lib/samples/vito_for_rails.rb +14 -0
  10. data/lib/vito.rb +2 -2
  11. data/lib/vito/connection.rb +20 -27
  12. data/lib/vito/dsl/installation.rb +15 -0
  13. data/lib/vito/dsl/server.rb +17 -0
  14. data/lib/vito/dsl_file.rb +24 -0
  15. data/lib/vito/log.rb +7 -1
  16. data/lib/vito/operating_system.rb +1 -11
  17. data/lib/vito/operating_systems/ubuntu_10.rb +31 -0
  18. data/lib/vito/output.rb +21 -0
  19. data/lib/vito/recipe.rb +6 -3
  20. data/lib/vito/recipes/postgres.rb +104 -0
  21. data/lib/vito/recipes/rbenv.rb +10 -5
  22. data/lib/vito/shell_initializer.rb +7 -12
  23. data/lib/vito/version.rb +1 -1
  24. data/spec/acceptance/recipes/git_acceptance_spec.rb +20 -0
  25. data/spec/acceptance/recipes/postgres_acceptance_spec.rb +20 -0
  26. data/spec/acceptance/recipes/rbenv_acceptance_spec.rb +22 -0
  27. data/spec/acceptance/recipes/ruby_acceptance_spec.rb +24 -0
  28. data/spec/spec_helper.rb +10 -0
  29. data/spec/support/vagrant.rb +34 -0
  30. data/spec/vito/connection_spec.rb +7 -4
  31. data/spec/vito/dsl/installation_spec.rb +17 -0
  32. data/spec/vito/dsl/server_spec.rb +0 -0
  33. data/spec/vito/dsl_file_spec.rb +37 -0
  34. data/spec/vito/log_spec.rb +10 -1
  35. data/spec/vito/operating_system_spec.rb +16 -0
  36. data/spec/vito/operating_systems/ubuntu_10_spec.rb +29 -0
  37. data/spec/vito/output_spec.rb +27 -5
  38. data/spec/vito/recipe_spec.rb +78 -0
  39. data/spec/vito/recipes/git_spec.rb +1 -1
  40. data/spec/vito/recipes/ruby_spec.rb +7 -35
  41. data/spec/vito/shell_initializer_spec.rb +10 -51
  42. data/vito.rb +3 -2
  43. metadata +33 -15
  44. data/lib/vito/installation.rb +0 -13
  45. data/lib/vito/logger.rb +0 -15
  46. data/lib/vito/recipes_configuration.rb +0 -11
  47. data/lib/vito/server.rb +0 -15
  48. data/lib/vito/ssh.rb +0 -62
  49. data/spec/contracts/vito/installation_contract.rb +0 -8
  50. data/spec/vito/installation_spec.rb +0 -25
  51. data/spec/vito/recipes_configuration_spec.rb +0 -7
  52. data/spec/vito/recipes_spec.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 273dc6976a1c63197a0576ebe4ef79ec7270c0ed
4
- data.tar.gz: 01c117e4e67876913b201ca883bdcef79eb536a4
3
+ metadata.gz: 24b73b5ceaa70f360c97d0bb28e4d2ca8a9d8e1d
4
+ data.tar.gz: 2759c1d3f37d0994c6b1b271d9093a7e93db92c1
5
5
  SHA512:
6
- metadata.gz: c406ea381b7ae439ff5bac7670a67381e7f95382189a685882bef8c819e6f04291eb00bde33d17e37f439dc8f346ede010e1685496fabbe384057e2d2aacabcd
7
- data.tar.gz: e722b05a007fd7d19f59fa45b528bace134d56d73bdca3a3ed447d99f830310ca5c8c9b19cd2b9e721ed53ff41dbd260cc9b9497b415632ef9b41363e7ebba12
6
+ metadata.gz: 5fea002c81b1e578fcd42a913f594211a32d5414964d746f0af45a2d147b45f54445979d0a8c7f119debee9bacfbbd16a6831a03d19564c622916ef6ddfd3c10
7
+ data.tar.gz: 88ba9d0cc04185a0983bf31c76859ad9a3509b0570d0cb08e2e6d055b2ab145928cb2cce91b26d8d18409776176e635f7ab54117a1ea43d1e3f518545623c77f
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ test/version_tmp
17
17
  tmp
18
18
  .vagrant/
19
19
  .vagrant*
20
+ .DS_Store
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use "ruby-2.0.0-p0@vito"
data/README.md CHANGED
@@ -37,16 +37,42 @@ For now, it won't be hosted, just sending SSH messages instead.
37
37
 
38
38
  These are the packages that are currently working:
39
39
 
40
- rbenv, git, ruby
40
+ rbenv, git, ruby, postgres
41
41
 
42
42
  ## Usage
43
43
 
44
- Vito is not read for production yet.
44
+ Vito currently works only in development.
45
+
46
+ ## Documentation
47
+
48
+ [Read the documentation](http://github.com/kurko/vito/blob/master/docs/manual.md)
45
49
 
46
50
  ## Contributing
47
51
 
48
- 1. Fork it
49
- 2. Create your feature branch (`git checkout -b my-new-feature`)
50
- 3. Commit your changes (`git commit -am 'Added some feature'`)
51
- 4. Push to the branch (`git push origin my-new-feature`)
52
- 5. Create new Pull Request
52
+ Integration tests are run with Vagrant, you have to install it first. **Important**:
53
+ don't use the gem, but the newer packaged installation. In fact, you should
54
+ uninstall it (removing binstubs even) or Bundler will start complaining.
55
+
56
+ Once you clone the repo, run:
57
+
58
+ ```bash
59
+ $ rake setup:download_vagrant_box
60
+ ```
61
+
62
+ This will download a VirtualBox image, initialize it with Vagrant and take a
63
+ initial snapshot. Whenever you run a spec, we'll roll back to this snapshot
64
+ to test it in a clean slate.
65
+
66
+ Add recipes to the `recipes/` dir. You can base your recipe on the existing ones.
67
+
68
+ Also, take a look at the rake tasks for running specs, e.g `rake spec:unit`,
69
+ `rake spec:acceptance`, `rake spec:all` etc
70
+
71
+ Once you're ready to push:
72
+
73
+ 1. Fork the repo
74
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 4. Commit your changes (`git commit -am 'Added some feature'`)
76
+ 5. Run specs with `rake spec:all` (check `rake -T` for more options)
77
+ 6. Push to the branch (`git push origin my-new-feature`)
78
+ 7. Create new Pull Request
data/Rakefile CHANGED
@@ -1,6 +1,14 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
3
 
4
+ def take_snapshot(name = "vito_snapshot")
5
+ puts "Installing vagrant-vbox-snapshot to take a snapshot"
6
+ system "vagrant plugin install vagrant-vbox-snapshot"
7
+
8
+ puts "Taking a snapshot of the current vm state"
9
+ system "vagrant snapshot take #{name}"
10
+ end
11
+
4
12
  desc "Sets up a Vagrant box for running specs"
5
13
  namespace :setup do
6
14
  task :download_vagrant_box do
@@ -9,5 +17,32 @@ namespace :setup do
9
17
  system "vagrant box add ubuntu_spec_box http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box"
10
18
  puts "Initializing box with Vagrant"
11
19
  system "vagrant init ubuntu_spec_box"
20
+ take_snapshot("initial_box")
12
21
  end
13
22
  end
23
+
24
+ namespace :vagrant do
25
+ desc "Creates a snapshot of the current box state to be used in specs"
26
+ task :take_snapshot do
27
+ take_snapshot("initial_box")
28
+ end
29
+ end
30
+
31
+ namespace :spec do
32
+ desc "Runs all specs"
33
+ task all: ["spec:unit", "spec:acceptance"]
34
+
35
+ desc "Runs specs by setting up a Vagrant box and installing recipes in it (could take minutes)"
36
+ task :acceptance do
37
+ puts "Running spec using Vagrant boxes (this could take several minutes)"
38
+ system "bundle exec rspec spec/acceptance"
39
+ end
40
+
41
+ desc "Runs unit specs (no Vagrant box required)"
42
+ task :unit do
43
+ puts "Running unit specs"
44
+ system "bundle exec rspec spec/vito"
45
+ end
46
+ end
47
+
48
+ task default: ["spec:unit"]
data/Vagrantfile CHANGED
@@ -29,7 +29,7 @@ Vagrant::Config.run do |config|
29
29
 
30
30
  # Forward a port from the guest to the host, which allows for outside
31
31
  # computers to access the VM, whereas host only networking does not.
32
- config.vm.forward_port 23, 22
32
+ # config.vm.forward_port 23, 22
33
33
 
34
34
  # Share an additional folder to the guest VM. The first argument is
35
35
  # an identifier, the second is the path on the guest to mount the
data/bin/vito CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift File.expand_path('../../', __FILE__)
4
- require "lib/vito"
3
+ # Doing this so we can run the following in development (which doesn't have
4
+ # lib/ in the path)
5
+ #
6
+ # $ ./bin/vito
7
+ #
8
+ $LOAD_PATH.unshift File.expand_path('../../lib/', __FILE__)
9
+ require "vito"
5
10
 
6
11
  shell = Vito::ShellInitializer.new(ARGV)
7
12
  shell.run
data/docs/manual.md ADDED
@@ -0,0 +1,79 @@
1
+ _Atention: At this moment, this guide is our roadmap, not the actual manual._
2
+
3
+ ## API guide
4
+
5
+ **Vito** uses a recipes file called `vito.rb` to determine what servers should
6
+ be installed. The `vito.rb` defines servers and theirs programs. An example:
7
+
8
+ ```ruby
9
+ server :linode do
10
+ # Vagrant box
11
+ connection :ssh, command: "ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222"
12
+
13
+ install :rbenv
14
+ install :git
15
+ install :ruby, version: "1.9.3-p125"
16
+ install :postgres
17
+ install :tmux
18
+ install :ruby_gem, :bundler
19
+ install :passenger
20
+ end
21
+ ```
22
+
23
+ Here, we define the connection to the server and what should be installed in it.
24
+
25
+ ## Getting started
26
+
27
+ Install Vito with
28
+
29
+ `$ gem install vito`
30
+
31
+ ## Command-line
32
+
33
+ The following command will run Vito and try to load `vito.rb` file from the
34
+ current path.
35
+
36
+ `$ vito`
37
+
38
+ You can also define a particular file with
39
+
40
+ `$ vito my_file.rb`
41
+
42
+ Run `vito help` to see the available options you have.
43
+
44
+ ## The `vito.rb` file
45
+
46
+ ### connection(type, options)
47
+
48
+ Defines the connection to the server. The possible types are:
49
+
50
+ **ssh:** the server will be accessed via SSH. The possible options are:
51
+
52
+ * `command`: when you want to specify just a prefix, such as
53
+ `ssh deploy@12.34.56.78` or `vagrant ssh -c`. If you used the last, Vito would
54
+ send a command such as `vagrant ssh -c "rbenv install 1.9.3-p125"`. When
55
+ defining a command, you don't need to define other options (because the username
56
+ and host will already be included).
57
+ * `username`: if you define a username, you have to define a host.
58
+ * `host`
59
+ * `port`: defaults to 22
60
+ * `key`: path to file containing public key needed for the connection
61
+
62
+ **local:** when the server is the machine Vito is already running.
63
+
64
+ ### install(program, options = {}, &block)
65
+
66
+ Defines what program should be installed. For a list of available programs, type
67
+
68
+ `$ vito programs`
69
+
70
+ Some programs accept blocks, such as `passenger` (allows you to use Rails with
71
+ Apache or nginx):
72
+
73
+ ```ruby
74
+ install :passenger do
75
+ with :apache
76
+ # will open port 80, plus 443
77
+ vhosts_for :rails, with: :ssl, path: "/var/www/my_app/public"
78
+ end
79
+ ```
@@ -0,0 +1,14 @@
1
+ server :rails_server do
2
+ connection :ssh, user: "deploy", host: "0.0.0.0"
3
+
4
+ install :rbenv
5
+ install :git
6
+ install :ruby, version: "1.9.3-p125"
7
+ install :postgres
8
+ install :tmux
9
+ install :passenger do
10
+ with :apache
11
+ # will open port 80, plus 443
12
+ vhosts_for :rails, with: :ssl, path: "/var/www/my_app/public"
13
+ end
14
+ end
data/lib/vito.rb CHANGED
@@ -5,5 +5,5 @@ require "active_support/inflector"
5
5
  module Vito
6
6
  end
7
7
 
8
- Dir["lib/vito/**/*.rb"].each { |f| require f }
9
-
8
+ current_path = File.expand_path("../", __FILE__)
9
+ Dir["#{current_path}/vito/**/*.rb"].each { |f| require f }
@@ -5,6 +5,8 @@ module Vito
5
5
  def initialize(type, args = {})
6
6
  @options = {}
7
7
  @options[:command] = args[:command]
8
+ @options[:verbose] = args[:verbose] || false
9
+ @options[:silent] = args[:silent] || false
8
10
  end
9
11
 
10
12
  def query(command)
@@ -14,48 +16,39 @@ module Vito
14
16
 
15
17
  def run(command)
16
18
  command = final_command(command)
17
- Log.write "* Executing: #{command}"
19
+ Log.write("* Executing: #{command}") unless silent?
18
20
  output = execute_command(command)
19
21
 
22
+ Log.write(output.result, verbose?)
20
23
  unless output.success?
21
- Log.write "An error occurred. Here's the stacktrace:"
22
- Log.write output.result
23
- Log.write ""
24
+ Log.raise "An error occurred. Here's the stacktrace:"
25
+ Log.raise output.result
26
+ Log.raise ""
27
+ raise "Error."
24
28
  end
25
29
 
26
30
  output
27
31
  end
28
32
 
29
- class Output
30
- def initialize(stdin, stdout, stderr, thread)
31
- @stdout = stdout
32
- @stderr = stderr
33
- @thread = thread.value
34
- end
33
+ private
35
34
 
36
- def success?
37
- @thread.exitstatus == 0
38
- end
35
+ attr_reader :options
39
36
 
40
- def result
41
- if success?
42
- @stdout.read
43
- else
44
- @stderr.read
45
- end
46
- end
37
+ def verbose?
38
+ @options[:verbose]
47
39
  end
48
40
 
49
- private
50
-
51
- attr_reader :options
41
+ def silent?
42
+ @options[:silent]
43
+ end
52
44
 
53
45
  def execute_command(command)
54
46
  stdin, stdout, stderr, thread = []
55
- Bundler.with_clean_env do
56
- stdin, stdout, stderr, thread = Open3.popen3(command)
57
- end
58
- Output.new(stdin, stdout, stderr, thread)
47
+ # In case we're in development and running `vagrant ssh -c`
48
+ #Bundler.with_clean_env do
49
+ stdin, stdout, stderr, thread = Open3.popen3(command)
50
+ #end
51
+ Vito::ConnectionOutput.new(stdin, stdout, stderr, thread)
59
52
  end
60
53
 
61
54
  def final_command(command)
@@ -0,0 +1,15 @@
1
+ module Vito
2
+ module Dsl
3
+ class Installation
4
+ def initialize(name, options, connection)
5
+ @name = name.to_s
6
+ @options = options
7
+ @connection = connection
8
+ end
9
+
10
+ def install
11
+ "Vito::Recipes::#{@name.camelize}".constantize.new(@options, @connection).run
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Vito
2
+ module Dsl
3
+ class Server
4
+ def initialize(args = nil)
5
+ @args = args
6
+ end
7
+
8
+ def connection(type, options = {})
9
+ @connection ||= Vito::Connection.new(type, options)
10
+ end
11
+
12
+ def install(name, options = {})
13
+ Vito::Dsl::Installation.new(name, options, @connection).install
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module Vito
2
+ class DslFile
3
+ def initialize(argv = nil)
4
+ @argv = argv
5
+ end
6
+
7
+ def run(code_string = nil, &block)
8
+ if block_given?
9
+ instance_eval(&block)
10
+ else
11
+ instance_eval(code_string)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :options
18
+
19
+ # called by the vito.rb file
20
+ def server(*args, &block)
21
+ Vito::Dsl::Server.new(args).instance_eval(&block)
22
+ end
23
+ end
24
+ end
data/lib/vito/log.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  module Vito
2
2
  class Log
3
- def self.write(string)
3
+ def self.write(string, output_to_stdout = true)
4
+ if ENV["env"] != "test"
5
+ puts string if output_to_stdout
6
+ end
7
+ end
8
+
9
+ def self.raise(string)
4
10
  puts string
5
11
  end
6
12
 
@@ -4,18 +4,8 @@ module Vito
4
4
  @connection = connection
5
5
  end
6
6
 
7
- def update_packages
8
- os.update_packages
9
- end
10
-
11
- def install_dependencies(dependencies)
12
- os.install_dependencies(dependencies)
13
- end
14
-
15
- private
16
-
17
7
  def os
18
- @os ||= Vito::OperatingSystem::Ubuntu10.new(@connection)
8
+ @os ||= Vito::OperatingSystems::Ubuntu10.new(@connection)
19
9
  end
20
10
  end
21
11
  end
@@ -0,0 +1,31 @@
1
+ module Vito
2
+ module OperatingSystems
3
+ class Ubuntu10
4
+ NAME = :ubuntu
5
+ VERSION = "10"
6
+
7
+ def initialize(connection)
8
+ @connection = connection
9
+ end
10
+
11
+ def is?(name, version = nil)
12
+ version = VERSION unless version
13
+ name == NAME && version.to_s == VERSION
14
+ end
15
+
16
+ def update_packages
17
+ @connection.run("sudo apt-get update")
18
+ end
19
+
20
+ def install_dependencies(dependencies)
21
+ @connection.run("sudo apt-get install -y #{dependencies.join(" ")}")
22
+ end
23
+
24
+ private
25
+
26
+ def version
27
+ 10
28
+ end
29
+ end
30
+ end
31
+ end