engineyard-local 0.2.1

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 (70) hide show
  1. data/.gitignore +23 -0
  2. data/Gemfile +15 -0
  3. data/Gemfile.lock +62 -0
  4. data/README.md +115 -0
  5. data/Rakefile +15 -0
  6. data/bin/ey-local +4 -0
  7. data/config/dna.json +206 -0
  8. data/config/locales/en.yml +57 -0
  9. data/config/settings.yml +18 -0
  10. data/config/solo.rb +7 -0
  11. data/engineyard-local.gemspec +24 -0
  12. data/install/deb/README.md +72 -0
  13. data/install/deb/Rakefile +157 -0
  14. data/install/deb/Vagrantfile +10 -0
  15. data/install/deb/install.sh +32 -0
  16. data/install/osx/README.md +23 -0
  17. data/install/osx/Rakefile +39 -0
  18. data/install/osx/engineyard-local/engineyard-local.pkgproj +812 -0
  19. data/install/osx/images/eylocal_installer.png +0 -0
  20. data/install/osx/scripts/log.sh +3 -0
  21. data/install/osx/scripts/postinstall +57 -0
  22. data/install/osx/scripts/rvm_install.sh +34 -0
  23. data/lib/engineyard-local.rb +42 -0
  24. data/lib/engineyard-local/command.rb +65 -0
  25. data/lib/engineyard-local/command/base.rb +15 -0
  26. data/lib/engineyard-local/command/exec.rb +11 -0
  27. data/lib/engineyard-local/command/group.rb +86 -0
  28. data/lib/engineyard-local/command/helpers.rb +23 -0
  29. data/lib/engineyard-local/command/list.rb +29 -0
  30. data/lib/engineyard-local/command/rails.rb +19 -0
  31. data/lib/engineyard-local/command/up.rb +87 -0
  32. data/lib/engineyard-local/command/vagrant_action.rb +11 -0
  33. data/lib/engineyard-local/errors.rb +10 -0
  34. data/lib/engineyard-local/middleware.rb +28 -0
  35. data/lib/engineyard-local/middleware/bundle.rb +40 -0
  36. data/lib/engineyard-local/middleware/chef.rb +44 -0
  37. data/lib/engineyard-local/middleware/default_provisioner.rb +34 -0
  38. data/lib/engineyard-local/middleware/dna.rb +80 -0
  39. data/lib/engineyard-local/middleware/exec.rb +27 -0
  40. data/lib/engineyard-local/middleware/helpers.rb +4 -0
  41. data/lib/engineyard-local/middleware/helpers/executable.rb +27 -0
  42. data/lib/engineyard-local/middleware/helpers/network.rb +20 -0
  43. data/lib/engineyard-local/middleware/helpers/rvm.rb +37 -0
  44. data/lib/engineyard-local/middleware/helpers/uploadable.rb +14 -0
  45. data/lib/engineyard-local/middleware/network.rb +64 -0
  46. data/lib/engineyard-local/middleware/rails.rb +3 -0
  47. data/lib/engineyard-local/middleware/rails/command.rb +31 -0
  48. data/lib/engineyard-local/middleware/rails/db.rb +36 -0
  49. data/lib/engineyard-local/middleware/rails/install.rb +36 -0
  50. data/lib/engineyard-local/middleware/rails/new.rb +31 -0
  51. data/lib/engineyard-local/middleware/tag.rb +33 -0
  52. data/lib/engineyard-local/ui.rb +33 -0
  53. data/lib/engineyard-local/version.rb +5 -0
  54. data/lib/engineyard-local/virtualbox.rb +35 -0
  55. data/lib/vagrant_init.rb +1 -0
  56. data/test/engineyard-local/command/group_test.rb +34 -0
  57. data/test/engineyard-local/command/up_test.rb +70 -0
  58. data/test/engineyard-local/command_test.rb +40 -0
  59. data/test/engineyard-local/middelware/bundle_test.rb +32 -0
  60. data/test/engineyard-local/middelware/default_provisioner_test.rb +35 -0
  61. data/test/engineyard-local/middelware/exec_test.rb +19 -0
  62. data/test/engineyard-local/middelware/network_test.rb +94 -0
  63. data/test/engineyard-local/middelware/rails/command_test.rb +24 -0
  64. data/test/engineyard-local/middelware/rails/db_test.rb +23 -0
  65. data/test/engineyard-local/middelware/rails/install_test.rb +24 -0
  66. data/test/engineyard-local/ui_test.rb +22 -0
  67. data/test/engineyard-local/virtualbox_test.rb +34 -0
  68. data/test/integration/up_test.rb +28 -0
  69. data/test/test_helper.rb +78 -0
  70. metadata +178 -0
@@ -0,0 +1,3 @@
1
+ require "engineyard-local/middleware/rails/db"
2
+ require "engineyard-local/middleware/rails/command"
3
+ require "engineyard-local/middleware/rails/install"
@@ -0,0 +1,31 @@
1
+ module Engineyard
2
+ module Local
3
+ module Middleware
4
+ module Rails
5
+ class Command
6
+ include Middleware::Helpers::Rvm
7
+ include Middleware::Helpers::Executable
8
+
9
+ def initialize(app, env)
10
+ @app, @env = app, env
11
+ end
12
+
13
+ def call(env)
14
+ ssh_exec!(env, commands)
15
+ @app.call(env)
16
+ end
17
+
18
+ def commands
19
+ rvm_env +
20
+ [ "cd #{project_dir}",
21
+ "rails #{command_args}" ]
22
+ end
23
+
24
+ def command_args
25
+ @env["eylocal.rails.command_args"].join(" ")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ module Engineyard
2
+ module Local
3
+ module Middleware
4
+ module Rails
5
+ class DB
6
+ include Middleware::Helpers::Rvm
7
+ include Middleware::Helpers::Executable
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @env = env
12
+ end
13
+
14
+ def call(env)
15
+ @env[:ui].info I18n.t("eylocal.setup.rails.db")
16
+ ssh_exec!(env, commands)
17
+ @app.call(env)
18
+ end
19
+
20
+ def commands
21
+ rvm_env +
22
+ [ "cd #{project_dir}",
23
+ if_task_exists("db:create"),
24
+ if_task_exists("db:migrate") ]
25
+ end
26
+
27
+ # if there's a Rakefile, and rake -T contains the task we're looking for
28
+ # execute the task
29
+ def if_task_exists(task)
30
+ "if [[ `rake -T > /dev/null 2>&1 && rake -T | grep -e '#{task}'` ]]; then rake #{task}; fi"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,36 @@
1
+ module Engineyard
2
+ module Local
3
+ module Middleware
4
+ module Rails
5
+ class Install
6
+ include Middleware::Helpers::Rvm
7
+ include Middleware::Helpers::Executable
8
+
9
+ def initialize(app, env)
10
+ @app, @env = app, env
11
+ end
12
+
13
+ def call(env)
14
+ ssh_exec!(env, commands)
15
+ @app.call(env)
16
+ end
17
+
18
+ def commands
19
+ rvm_env +
20
+ [ unless_rails("gem install rails #{install_opts}") ]
21
+ end
22
+
23
+ def install_opts
24
+ if @env["eylocal.rails.version"]
25
+ "--version=#{@env["eylocal.rails.version"]}"
26
+ end
27
+ end
28
+
29
+ def unless_rails(cmd)
30
+ "gem list rails | grep rails; if [[ $? -gt 0 ]]; then sudo #{cmd}; fi"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ module Engineyard
2
+ module Local
3
+ module Middleware
4
+ module Rails
5
+ class New
6
+ include Middleware::Helpers::Rvm
7
+ include Middleware::Helpers::Executable
8
+
9
+ def initialize(app, env, opts)
10
+ @app, @env, @opts = app, env, opts
11
+ end
12
+
13
+ def call(env)
14
+ ssh_exec!(env, commands)
15
+ @app.call(env)
16
+ end
17
+
18
+ def commands
19
+ rvm_env +
20
+ [ "cd #{project_dir}",
21
+ "rails #{command_args}" ]
22
+ end
23
+
24
+ def command_args
25
+ @opts["eylocal.rails.command_args"].join(" ")
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'digest/sha1'
2
+
3
+ module Engineyard
4
+ module Local
5
+ module Middleware
6
+ class Tag
7
+ include Helpers::Network
8
+
9
+ def initialize(app, env)
10
+ @app, @env = app, env
11
+ end
12
+
13
+ def call(env)
14
+ @env[:ui].info I18n.t("eylocal.tag")
15
+ tag_vm(env)
16
+ @app.call(env)
17
+ end
18
+
19
+ def tag_vm(env)
20
+ value = env[:root_path].to_s
21
+
22
+ # mark the vm as ey-local for listing
23
+ set_extra_data(env, Local.config[:managed_vm_key], value)
24
+ set_extra_data(env, Local.config[:network_ip_key], proposed_ip)
25
+ end
26
+
27
+ def set_extra_data(env, key, value)
28
+ env[:vm].driver.execute("setextradata", env[:vm].uuid, key, value)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ module Engineyard
2
+ module Local
3
+ module UI
4
+ module Common
5
+ def ey_localize(message)
6
+ # TODO this is likely to be insufficient but it's a start
7
+ # toward making sure the ui is consistent for the user
8
+ message.gsub(/([Aa]) (`)?[Vv]agrant /, '\1n \2ey-local ').gsub(/[Vv]agrant /, 'ey-local ')
9
+ end
10
+
11
+ def say(type, message, opts=nil)
12
+ super(type, ey_localize(message), opts)
13
+ end
14
+ end
15
+
16
+ class Basic < Vagrant::UI::Basic
17
+ include Common
18
+
19
+ def initialize(resource)
20
+ super(Local.config[:commands][:prefix])
21
+ end
22
+ end
23
+
24
+ class Colored < Vagrant::UI::Colored
25
+ include Common
26
+
27
+ def initialize(resource)
28
+ super(Local.config[:commands][:prefix])
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module Engineyard
2
+ module Local
3
+ VERSION = "0.2.1"
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ module Engineyard
2
+ module Local
3
+ class Virtualbox
4
+ VALUE_PREFIX = "Value: "
5
+ # TODO this is exceptionally difficult to read
6
+ INFO_REGEX = /"(.*)".*\{(.*)\}/
7
+
8
+ def self.uuid_map
9
+ # TODO ~~~ is fragile
10
+ # extract the uuids from `VBoxMange list vms`, sample output:
11
+ # "Bar VM" {c21b5de6-5867-4471-ab53-7af23badc5eb}
12
+ # "Foo VM" {aaba8c3a-3521-46e2-bd2c-fe7e65b77524}
13
+ info_list = vbox.execute("list", "vms").gsub(INFO_REGEX, '\1~~~\2').split("\n")
14
+
15
+ info_list.inject({}) do |acc, info|
16
+ name, uuid = info.split("~~~")
17
+ acc[name] = uuid
18
+ acc
19
+ end
20
+ end
21
+
22
+ def self.extra_data(uuid, key = "enumerate" )
23
+ value = vbox.execute("getextradata", uuid, key).strip
24
+
25
+ if value.include?(VALUE_PREFIX)
26
+ value.gsub!(/#{VALUE_PREFIX}/, '')
27
+ end
28
+ end
29
+
30
+ def self.vbox
31
+ @@vbox ||= Vagrant::Driver::VirtualBox.new
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1 @@
1
+ require "engineyard-local"
@@ -0,0 +1,34 @@
1
+ require "test_helper"
2
+
3
+ class CommandGroupTest < Test::Unit::TestCase
4
+ include Vagrant::TestHelpers
5
+
6
+ context "log" do
7
+ setup do
8
+ @cmd = Engineyard::Local::Command::Group.new([], {}, {:env => @env})
9
+ @klass = Engineyard::Local::Command::Group
10
+ @app, @env = action_env
11
+ @klass.env = @env
12
+ @cmd.stubs(:options).returns({"lines" => 100, "environment" => "development"})
13
+ end
14
+
15
+ should "exec tail with flagged lines" do
16
+ Engineyard::Local::Command::Exec
17
+ .any_instance.expects(:run)
18
+ .with(Engineyard::Local::Middleware::Exec, { "eylocal.exec.command_args" => ["tail -10 log/development.log"]})
19
+
20
+
21
+ @cmd.expects(:options).twice.returns({"lines" => 10, "environment" => "development"})
22
+ @cmd.log()
23
+ end
24
+
25
+ should "exec tail with flagged environment" do
26
+ Engineyard::Local::Command::Exec
27
+ .any_instance.expects(:run)
28
+ .with(Engineyard::Local::Middleware::Exec, { "eylocal.exec.command_args" => ["tail -100 log/foo.log"]})
29
+
30
+ @cmd.expects(:options).twice.returns({"lines" => 100, "environment" => "foo"})
31
+ @cmd.log()
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,70 @@
1
+ require "test_helper"
2
+
3
+ class CommandUpTest < Test::Unit::TestCase
4
+ include Vagrant::TestHelpers
5
+
6
+ context "up" do
7
+ setup do
8
+ @klass = Engineyard::Local::Command::Up
9
+ @config = Engineyard::Local.config
10
+ @env = vagrant_env
11
+
12
+ # TODO this is clearly bad, using env.cli in the commands
13
+ # makes it hard to mock/expect
14
+ @cmd = Engineyard::Local::Command::Group.new([], {}, {:env => @env})
15
+
16
+ # prevent the bundle middleware from executing
17
+ @klass.any_instance.stubs(:with_target_vms).returns([])
18
+ @klass.any_instance.stubs(:env).returns(@env)
19
+
20
+ @env.stubs(:cli)
21
+ @env.stubs(:root_path).returns(nil)
22
+ end
23
+
24
+ should "add a box with config default params when invoked" do
25
+ default_name = @config[:box_defaults][:name]
26
+ default_uri = @config[:box_defaults][:uri]
27
+
28
+ @env.expects(:cli).with("box", "add", default_name, default_uri)
29
+ @env.expects(:cli).with("init", default_name)
30
+ @cmd.up
31
+ end
32
+
33
+ should "add a box with passed params when invoked" do
34
+ name = "foo"
35
+ uri = "http://foo.com"
36
+
37
+ @env.expects(:cli).with("box", "add", name, uri)
38
+ @env.expects(:cli).with("init", name)
39
+ @cmd.up(name, uri)
40
+ end
41
+
42
+ should "default to the installed box when its preset" do
43
+ default_name = @config[:box_defaults][:name]
44
+
45
+ Engineyard::Local.expects(:project_root).returns("/foo/")
46
+ File.expects(:exists?).with("/foo/default.box").returns(true)
47
+
48
+ @env.expects(:cli).with("box", "add", default_name, "/foo/default.box")
49
+ @env.expects(:cli).with("init", default_name)
50
+ @cmd.up
51
+ end
52
+
53
+ context "bundling" do
54
+ setup do
55
+ @env.stubs(:cli)
56
+ Vagrant::Action::Builder.any_instance.stubs(:use)
57
+ end
58
+
59
+ should "skip bundle when --no-bundle is included on the cli" do
60
+ Vagrant::Action::Builder.any_instance.expects(:use).with(Engineyard::Local::Middleware::Bundle).never
61
+ @cmd.up("--no-bundle")
62
+ end
63
+
64
+ should "run bundle by default" do
65
+ Vagrant::Action::Builder.any_instance.expects(:use).with(Engineyard::Local::Middleware::Bundle)
66
+ @cmd.up
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,40 @@
1
+ require "test_helper"
2
+
3
+ class CommandTest < Test::Unit::TestCase
4
+ include Vagrant::TestHelpers
5
+
6
+ context "Command" do
7
+ setup do
8
+ @klass = Engineyard::Local::Command
9
+ @cmdgrp = Engineyard::Local::Command::Group
10
+ @klass.stubs(:passthrough).returns(["foo"])
11
+ @klass.stubs(:all).returns(["foo", "bar"])
12
+
13
+ @app, @env = action_env
14
+ @klass.stubs(:vagrant_env).returns(@env)
15
+ end
16
+
17
+ should "not start Thor when command is member of passthrough set" do
18
+ # add description for the expected method below to prevent
19
+ # thor warning
20
+ @cmdgrp.desc("foo", "desc")
21
+
22
+ @cmdgrp.any_instance.expects(:foo).once
23
+ @cmdgrp.expects(:start).never
24
+
25
+ @klass.dispatch(["foo"])
26
+ end
27
+
28
+ should "start thor when the command is not passthrough" do
29
+ @cmdgrp.expects(:start).once
30
+
31
+ @klass.dispatch(["bar"])
32
+ end
33
+
34
+ should "return false when the command isn't included defined by ey-local" do
35
+ args = ["not-there-at-all"]
36
+ @env.expects(:cli).with(args)
37
+ assert !@klass.dispatch(args)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,32 @@
1
+ require "test_helper"
2
+
3
+ class BundleTest < Test::Unit::TestCase
4
+ include Vagrant::TestHelpers
5
+ include Engineyard::Local::TestHelpers
6
+
7
+ context "bundle" do
8
+ setup do
9
+ @app, @env = action_env
10
+ @middleware = Engineyard::Local::Middleware::Bundle.new(@app, @env)
11
+ end
12
+
13
+ should "provide the project directory" do
14
+ # TODO reference default config
15
+ assert_equal(@middleware.project_dir, "/vagrant")
16
+ end
17
+
18
+ should "setup the users environment for the ssh session (rvm)" do
19
+ assert(joined_commands.include?("/etc/profile.d/"))
20
+ end
21
+
22
+ should "set the rvm environment and gemset" do
23
+ # rvm command
24
+ assert(joined_commands.include?("rvm use"))
25
+ end
26
+
27
+ should "execute the commands necessary to install bundle in the app gemset" do
28
+ mock_ssh_channel(@env).expects(:execute).with(joined_commands)
29
+ @middleware.call(@env)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ require "test_helper"
2
+
3
+ class DefaultProvisionerTest < Test::Unit::TestCase
4
+ include Vagrant::TestHelpers
5
+ include Engineyard::Local::TestHelpers
6
+
7
+ context "defaulting the provisioner" do
8
+ setup do
9
+ @app, @env = action_env
10
+ @middleware = Engineyard::Local::Middleware::DefaultProvisioner.new(@app, @env)
11
+ end
12
+
13
+ should "not alter the provisioners list when the recipe doesn't exist" do
14
+ @middleware.expects(:default_recipe_path).returns("/will-not-exist")
15
+ @env[:vm].config.vm.expects(:provision).never
16
+ @middleware.call(@env)
17
+ end
18
+
19
+ should "not alter the provisioners list when another is configured" do
20
+ # ensure file check passes
21
+ @middleware.expects(:default_recipe_path).returns(File.expand_path(__FILE__))
22
+ @middleware.expects(:provisioner_configured?).returns(true)
23
+ @env[:vm].config.vm.expects(:provision).never
24
+ @middleware.call(@env)
25
+ end
26
+
27
+ should "add a provisioner when the recipe exists and there are no other provisioners" do
28
+ # ensure file check passes, called twice for the ui output
29
+ @middleware.expects(:default_recipe_path).twice.returns(File.expand_path(__FILE__))
30
+ @middleware.expects(:provisioner_configured?).returns(false)
31
+ @env[:vm].config.vm.expects(:provision).once
32
+ @middleware.call(@env)
33
+ end
34
+ end
35
+ end